✨ Publisher list on account
This commit is contained in:
		| @@ -9,6 +9,7 @@ import 'package:gap/gap.dart'; | ||||
| import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||||
| import 'package:island/models/chat.dart'; | ||||
| import 'package:island/models/developer.dart'; | ||||
| import 'package:island/models/publisher.dart'; | ||||
| import 'package:island/models/relationship.dart'; | ||||
| import 'package:island/models/account.dart'; | ||||
| import 'package:island/pods/config.dart'; | ||||
| @@ -224,7 +225,13 @@ class _AccountProfileDetail extends StatelessWidget { | ||||
|           spacing: 6, | ||||
|           children: [ | ||||
|             Icon(Symbols.fingerprint, size: 17, fill: 1).padding(right: 2), | ||||
|             Text(data.id), | ||||
|             Flexible( | ||||
|               child: Text( | ||||
|                 data.id, | ||||
|                 maxLines: 1, | ||||
|                 overflow: TextOverflow.ellipsis, | ||||
|               ), | ||||
|             ), | ||||
|           ], | ||||
|         ), | ||||
|         onTap: () { | ||||
| @@ -314,6 +321,56 @@ class _AccountProfileLinks extends StatelessWidget { | ||||
|   } | ||||
| } | ||||
|  | ||||
| class _AccountPublisherList extends StatelessWidget { | ||||
|   final List<SnPublisher> publishers; | ||||
|  | ||||
|   const _AccountPublisherList({required this.publishers}); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     if (publishers.isEmpty) return const SizedBox.shrink(); | ||||
|     return Card( | ||||
|       child: Column( | ||||
|         crossAxisAlignment: CrossAxisAlignment.start, | ||||
|         children: [ | ||||
|           Text( | ||||
|             'publishers', | ||||
|           ).tr().bold().padding(horizontal: 24, top: 12, bottom: 4), | ||||
|           for (final publisher in publishers) | ||||
|             ListTile( | ||||
|               title: Text(publisher.nick), | ||||
|               subtitle: | ||||
|                   publisher.bio.isNotEmpty | ||||
|                       ? Text( | ||||
|                         publisher.bio, | ||||
|                         maxLines: 3, | ||||
|                         overflow: TextOverflow.ellipsis, | ||||
|                       ) | ||||
|                       : null, | ||||
|               leading: ProfilePictureWidget( | ||||
|                 file: publisher.picture, | ||||
|                 borderRadius: publisher.type == 1 ? 8 : null, | ||||
|               ), | ||||
|               isThreeLine: true, | ||||
|               contentPadding: EdgeInsets.symmetric(horizontal: 24), | ||||
|               trailing: const Icon(Symbols.chevron_right), | ||||
|               shape: RoundedRectangleBorder( | ||||
|                 borderRadius: const BorderRadius.all(Radius.circular(8)), | ||||
|               ), | ||||
|               onTap: () { | ||||
|                 Navigator.pop(context, true); | ||||
|                 context.pushNamed( | ||||
|                   'publisherProfile', | ||||
|                   pathParameters: {'name': publisher.name}, | ||||
|                 ); | ||||
|               }, | ||||
|             ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| class _AccountAction extends StatelessWidget { | ||||
|   final SnAccount data; | ||||
|   final AsyncValue<SnRelationship?> accountRelationship; | ||||
| @@ -335,6 +392,7 @@ class _AccountAction extends StatelessWidget { | ||||
|   Widget build(BuildContext context) { | ||||
|     return Card( | ||||
|       child: Column( | ||||
|         spacing: 8, | ||||
|         children: [ | ||||
|           Row( | ||||
|             spacing: 8, | ||||
| @@ -427,6 +485,7 @@ class _AccountAction extends StatelessWidget { | ||||
|                   color: Theme.of(context).colorScheme.onError, | ||||
|                 ), | ||||
|                 style: ButtonStyle( | ||||
|                   visualDensity: VisualDensity.compact, | ||||
|                   backgroundColor: WidgetStatePropertyAll( | ||||
|                     Theme.of(context).colorScheme.error, | ||||
|                   ), | ||||
| @@ -533,6 +592,20 @@ Future<SnDeveloper?> accountBotDeveloper(Ref ref, String uname) async { | ||||
|   } | ||||
| } | ||||
|  | ||||
| @riverpod | ||||
| Future<List<SnPublisher>> accountPublishers(Ref ref, String id) async { | ||||
|   final apiClient = ref.watch(apiClientProvider); | ||||
|   try { | ||||
|     final resp = await apiClient.get('/sphere/publishers/of/$id'); | ||||
|     return resp.data | ||||
|         .map((e) => SnPublisher.fromJson(e)) | ||||
|         .cast<SnPublisher>() | ||||
|         .toList(); | ||||
|   } catch (err) { | ||||
|     return []; | ||||
|   } | ||||
| } | ||||
|  | ||||
| class AccountProfileScreen extends HookConsumerWidget { | ||||
|   final String name; | ||||
|   const AccountProfileScreen({super.key, required this.name}); | ||||
| @@ -625,8 +698,9 @@ class AccountProfileScreen extends HookConsumerWidget { | ||||
|     ); | ||||
|  | ||||
|     return account.when( | ||||
|       data: | ||||
|           (data) => AppScaffold( | ||||
|       data: (data) { | ||||
|         final accountPublishers = ref.watch(accountPublishersProvider(data.id)); | ||||
|         return AppScaffold( | ||||
|           isNoBackground: false, | ||||
|           appBar: | ||||
|               isWideScreen(context) | ||||
| @@ -657,9 +731,7 @@ class AccountProfileScreen extends HookConsumerWidget { | ||||
|                             style: TextStyle( | ||||
|                               color: | ||||
|                                   appbarColor.value ?? | ||||
|                                     Theme.of( | ||||
|                                       context, | ||||
|                                     ).appBarTheme.foregroundColor, | ||||
|                                   Theme.of(context).appBarTheme.foregroundColor, | ||||
|                               shadows: [appbarShadow], | ||||
|                             ), | ||||
|                           ), | ||||
| @@ -728,6 +800,11 @@ class AccountProfileScreen extends HookConsumerWidget { | ||||
|                         child: CustomScrollView( | ||||
|                           slivers: [ | ||||
|                             SliverGap(24), | ||||
|                             SliverToBoxAdapter( | ||||
|                               child: _AccountPublisherList( | ||||
|                                 publishers: accountPublishers.value ?? [], | ||||
|                               ), | ||||
|                             ), | ||||
|                             if (user.value != null && !isCurrentUser) | ||||
|                               SliverToBoxAdapter( | ||||
|                                 child: _AccountAction( | ||||
| @@ -837,6 +914,11 @@ class AccountProfileScreen extends HookConsumerWidget { | ||||
|                             data: data, | ||||
|                           ).padding(horizontal: 4), | ||||
|                         ), | ||||
|                       SliverToBoxAdapter( | ||||
|                         child: _AccountPublisherList( | ||||
|                           publishers: accountPublishers.value ?? [], | ||||
|                         ).padding(horizontal: 4), | ||||
|                       ), | ||||
|                       SliverToBoxAdapter( | ||||
|                         child: _AccountProfileDetail( | ||||
|                           data: data, | ||||
| @@ -863,7 +945,8 @@ class AccountProfileScreen extends HookConsumerWidget { | ||||
|                       ), | ||||
|                     ], | ||||
|                   ), | ||||
|           ), | ||||
|         ); | ||||
|       }, | ||||
|       error: | ||||
|           (error, stackTrace) => AppScaffold( | ||||
|             appBar: AppBar(leading: const PageBackButton()), | ||||
|   | ||||
| @@ -762,5 +762,127 @@ class _AccountBotDeveloperProviderElement | ||||
|   String get uname => (origin as AccountBotDeveloperProvider).uname; | ||||
| } | ||||
|  | ||||
| String _$accountPublishersHash() => r'25f5695b4a5154163d77f1769876d826bf736609'; | ||||
|  | ||||
| /// See also [accountPublishers]. | ||||
| @ProviderFor(accountPublishers) | ||||
| const accountPublishersProvider = AccountPublishersFamily(); | ||||
|  | ||||
| /// See also [accountPublishers]. | ||||
| class AccountPublishersFamily extends Family<AsyncValue<List<SnPublisher>>> { | ||||
|   /// See also [accountPublishers]. | ||||
|   const AccountPublishersFamily(); | ||||
|  | ||||
|   /// See also [accountPublishers]. | ||||
|   AccountPublishersProvider call(String id) { | ||||
|     return AccountPublishersProvider(id); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   AccountPublishersProvider getProviderOverride( | ||||
|     covariant AccountPublishersProvider provider, | ||||
|   ) { | ||||
|     return call(provider.id); | ||||
|   } | ||||
|  | ||||
|   static const Iterable<ProviderOrFamily>? _dependencies = null; | ||||
|  | ||||
|   @override | ||||
|   Iterable<ProviderOrFamily>? get dependencies => _dependencies; | ||||
|  | ||||
|   static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null; | ||||
|  | ||||
|   @override | ||||
|   Iterable<ProviderOrFamily>? get allTransitiveDependencies => | ||||
|       _allTransitiveDependencies; | ||||
|  | ||||
|   @override | ||||
|   String? get name => r'accountPublishersProvider'; | ||||
| } | ||||
|  | ||||
| /// See also [accountPublishers]. | ||||
| class AccountPublishersProvider | ||||
|     extends AutoDisposeFutureProvider<List<SnPublisher>> { | ||||
|   /// See also [accountPublishers]. | ||||
|   AccountPublishersProvider(String id) | ||||
|     : this._internal( | ||||
|         (ref) => accountPublishers(ref as AccountPublishersRef, id), | ||||
|         from: accountPublishersProvider, | ||||
|         name: r'accountPublishersProvider', | ||||
|         debugGetCreateSourceHash: | ||||
|             const bool.fromEnvironment('dart.vm.product') | ||||
|                 ? null | ||||
|                 : _$accountPublishersHash, | ||||
|         dependencies: AccountPublishersFamily._dependencies, | ||||
|         allTransitiveDependencies: | ||||
|             AccountPublishersFamily._allTransitiveDependencies, | ||||
|         id: id, | ||||
|       ); | ||||
|  | ||||
|   AccountPublishersProvider._internal( | ||||
|     super._createNotifier, { | ||||
|     required super.name, | ||||
|     required super.dependencies, | ||||
|     required super.allTransitiveDependencies, | ||||
|     required super.debugGetCreateSourceHash, | ||||
|     required super.from, | ||||
|     required this.id, | ||||
|   }) : super.internal(); | ||||
|  | ||||
|   final String id; | ||||
|  | ||||
|   @override | ||||
|   Override overrideWith( | ||||
|     FutureOr<List<SnPublisher>> Function(AccountPublishersRef provider) create, | ||||
|   ) { | ||||
|     return ProviderOverride( | ||||
|       origin: this, | ||||
|       override: AccountPublishersProvider._internal( | ||||
|         (ref) => create(ref as AccountPublishersRef), | ||||
|         from: from, | ||||
|         name: null, | ||||
|         dependencies: null, | ||||
|         allTransitiveDependencies: null, | ||||
|         debugGetCreateSourceHash: null, | ||||
|         id: id, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   AutoDisposeFutureProviderElement<List<SnPublisher>> createElement() { | ||||
|     return _AccountPublishersProviderElement(this); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   bool operator ==(Object other) { | ||||
|     return other is AccountPublishersProvider && other.id == id; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   int get hashCode { | ||||
|     var hash = _SystemHash.combine(0, runtimeType.hashCode); | ||||
|     hash = _SystemHash.combine(hash, id.hashCode); | ||||
|  | ||||
|     return _SystemHash.finish(hash); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @Deprecated('Will be removed in 3.0. Use Ref instead') | ||||
| // ignore: unused_element | ||||
| mixin AccountPublishersRef on AutoDisposeFutureProviderRef<List<SnPublisher>> { | ||||
|   /// The parameter `id` of this provider. | ||||
|   String get id; | ||||
| } | ||||
|  | ||||
| class _AccountPublishersProviderElement | ||||
|     extends AutoDisposeFutureProviderElement<List<SnPublisher>> | ||||
|     with AccountPublishersRef { | ||||
|   _AccountPublishersProviderElement(super.provider); | ||||
|  | ||||
|   @override | ||||
|   String get id => (origin as AccountPublishersProvider).id; | ||||
| } | ||||
|  | ||||
| // ignore_for_file: type=lint | ||||
| // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package | ||||
|   | ||||
| @@ -66,8 +66,8 @@ class _PublisherBasisWidget extends StatelessWidget { | ||||
|             ), | ||||
|           ), | ||||
|           onTap: () { | ||||
|             Navigator.pop(context, true); | ||||
|             if (data.account?.name != null) { | ||||
|               Navigator.pop(context, true); | ||||
|               context.pushNamed( | ||||
|                 'accountProfile', | ||||
|                 pathParameters: {'name': data.account!.name}, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user