✨ Able to see realm affiliated publishers on realm view
This commit is contained in:
		| @@ -128,6 +128,7 @@ | ||||
|     "one": "{} social point", | ||||
|     "other": "{} social points" | ||||
|   }, | ||||
|   "publisherAffiliatedBy": "Affiliated by {}", | ||||
|   "publisherRunBy": "Run by {}", | ||||
|   "fieldPublisherBelongToRealm": "Belongs to", | ||||
|   "fieldPublisherBelongToRealmUnset": "Unset Publisher Belongs to Realm", | ||||
|   | ||||
| @@ -112,6 +112,7 @@ | ||||
|     "one": "{} 点社会信用点", | ||||
|     "other": "{} 点社会信用点" | ||||
|   }, | ||||
|   "publisherAffiliatedBy": "隶属于 {}", | ||||
|   "publisherRunBy": "由 {} 管理", | ||||
|   "fieldPublisherBelongToRealm": "所属领域", | ||||
|   "fieldPublisherBelongToRealmUnset": "未设置发布者所属领域", | ||||
|   | ||||
| @@ -14,6 +14,7 @@ import 'package:surface/providers/sn_network.dart'; | ||||
| import 'package:surface/providers/user_directory.dart'; | ||||
| import 'package:surface/types/account.dart'; | ||||
| import 'package:surface/types/post.dart'; | ||||
| import 'package:surface/types/realm.dart'; | ||||
| import 'package:surface/widgets/account/account_image.dart'; | ||||
| import 'package:surface/widgets/dialog.dart'; | ||||
| import 'package:surface/widgets/post/post_item.dart'; | ||||
| @@ -22,19 +23,19 @@ import 'package:very_good_infinite_list/very_good_infinite_list.dart'; | ||||
|  | ||||
| class PostPublisherScreen extends StatefulWidget { | ||||
|   final String name; | ||||
|  | ||||
|   const PostPublisherScreen({super.key, required this.name}); | ||||
|  | ||||
|   @override | ||||
|   State<PostPublisherScreen> createState() => _PostPublisherScreenState(); | ||||
| } | ||||
|  | ||||
| class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|     with SingleTickerProviderStateMixin { | ||||
| class _PostPublisherScreenState extends State<PostPublisherScreen> with SingleTickerProviderStateMixin { | ||||
|   late final ScrollController _scrollController = ScrollController(); | ||||
|   late final TabController _tabController = | ||||
|       TabController(length: 3, vsync: this); | ||||
|   late final TabController _tabController = TabController(length: 3, vsync: this); | ||||
|  | ||||
|   SnPublisher? _publisher; | ||||
|   SnRealm? _realm; | ||||
|   SnAccount? _account; | ||||
|  | ||||
|   Future<void> _fetchPublisher() async { | ||||
| @@ -45,11 +46,16 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|       if (!mounted) return; | ||||
|       _publisher = SnPublisher.fromJson(resp.data); | ||||
|       _account = await ud.getAccount(_publisher?.accountId); | ||||
|       if (_publisher?.realmId != null) { | ||||
|         final resp = await sn.client.get('/cgi/id/realms/${_publisher!.realmId}'); | ||||
|         _realm = SnRealm.fromJson(resp.data); | ||||
|       } | ||||
|     } catch (err) { | ||||
|       if (!mounted) return; | ||||
|       context.showErrorDialog(err).then((_) { | ||||
|         if (mounted) Navigator.pop(context); | ||||
|       }); | ||||
|       rethrow; | ||||
|     } finally { | ||||
|       setState(() {}); | ||||
|     } | ||||
| @@ -114,14 +120,12 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|   double _appBarBlur = 0.0; | ||||
|  | ||||
|   late final _appBarWidth = MediaQuery.of(context).size.width; | ||||
|   late final _appBarHeight = | ||||
|       (_appBarWidth * kBannerAspectRatio).roundToDouble(); | ||||
|   late final _appBarHeight = (_appBarWidth * kBannerAspectRatio).roundToDouble(); | ||||
|  | ||||
|   void _updateAppBarBlur() { | ||||
|     if (_scrollController.offset > _appBarHeight) return; | ||||
|     setState(() { | ||||
|       _appBarBlur = | ||||
|           (_scrollController.offset / _appBarHeight * 10).clamp(0.0, 10.0); | ||||
|       _appBarBlur = (_scrollController.offset / _appBarHeight * 10).clamp(0.0, 10.0); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
| @@ -215,10 +219,7 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                             text: TextSpan(children: [ | ||||
|                               TextSpan( | ||||
|                                 text: _publisher!.nick, | ||||
|                                 style: Theme.of(context) | ||||
|                                     .textTheme | ||||
|                                     .titleLarge! | ||||
|                                     .copyWith( | ||||
|                                 style: Theme.of(context).textTheme.titleLarge!.copyWith( | ||||
|                                       color: Colors.white, | ||||
|                                       shadows: labelShadows, | ||||
|                                     ), | ||||
| @@ -226,10 +227,7 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                               const TextSpan(text: '\n'), | ||||
|                               TextSpan( | ||||
|                                 text: '@${_publisher!.name}', | ||||
|                                 style: Theme.of(context) | ||||
|                                     .textTheme | ||||
|                                     .bodySmall! | ||||
|                                     .copyWith( | ||||
|                                 style: Theme.of(context).textTheme.bodySmall!.copyWith( | ||||
|                                       color: Colors.white, | ||||
|                                       shadows: labelShadows, | ||||
|                                     ), | ||||
| @@ -241,14 +239,19 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                         ? Stack( | ||||
|                             fit: StackFit.expand, | ||||
|                             children: [ | ||||
|                               UniversalImage( | ||||
|                                 sn.getAttachmentUrl(_publisher!.banner), | ||||
|                                 fit: BoxFit.cover, | ||||
|                                 height: imageHeight, | ||||
|                                 width: _appBarWidth, | ||||
|                                 cacheHeight: imageHeight, | ||||
|                                 cacheWidth: _appBarWidth, | ||||
|                               ), | ||||
|                               if (_publisher!.banner.isNotEmpty) | ||||
|                                 UniversalImage( | ||||
|                                   sn.getAttachmentUrl(_publisher!.banner), | ||||
|                                   fit: BoxFit.cover, | ||||
|                                   height: imageHeight, | ||||
|                                   width: _appBarWidth, | ||||
|                                   cacheHeight: imageHeight, | ||||
|                                   cacheWidth: _appBarWidth, | ||||
|                                 ) | ||||
|                               else | ||||
|                                 Container( | ||||
|                                   color: Theme.of(context).colorScheme.surfaceContainer, | ||||
|                                 ), | ||||
|                               Positioned( | ||||
|                                 top: 0, | ||||
|                                 left: 0, | ||||
| @@ -288,14 +291,11 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                                 const Gap(16), | ||||
|                                 Expanded( | ||||
|                                   child: Column( | ||||
|                                     crossAxisAlignment: | ||||
|                                         CrossAxisAlignment.start, | ||||
|                                     crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                                     children: [ | ||||
|                                       Text( | ||||
|                                         _publisher!.nick, | ||||
|                                         style: Theme.of(context) | ||||
|                                             .textTheme | ||||
|                                             .titleMedium, | ||||
|                                         style: Theme.of(context).textTheme.titleMedium, | ||||
|                                       ).bold(), | ||||
|                                       Text('@${_publisher!.name}').fontSize(13), | ||||
|                                     ], | ||||
| @@ -306,9 +306,7 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                                     style: ButtonStyle( | ||||
|                                       elevation: WidgetStatePropertyAll(0), | ||||
|                                     ), | ||||
|                                     onPressed: _isSubscribing | ||||
|                                         ? null | ||||
|                                         : _toggleSubscription, | ||||
|                                     onPressed: _isSubscribing ? null : _toggleSubscription, | ||||
|                                     label: Text('subscribe').tr(), | ||||
|                                     icon: const Icon(Symbols.add), | ||||
|                                   ) | ||||
| @@ -317,17 +315,14 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                                     style: ButtonStyle( | ||||
|                                       elevation: WidgetStatePropertyAll(0), | ||||
|                                     ), | ||||
|                                     onPressed: _isSubscribing | ||||
|                                         ? null | ||||
|                                         : _toggleSubscription, | ||||
|                                     onPressed: _isSubscribing ? null : _toggleSubscription, | ||||
|                                     label: Text('unsubscribe').tr(), | ||||
|                                     icon: const Icon(Symbols.remove), | ||||
|                                   ), | ||||
|                               ], | ||||
|                             ).padding(right: 8), | ||||
|                             const Gap(12), | ||||
|                             Text(_publisher!.description) | ||||
|                                 .padding(horizontal: 8), | ||||
|                             Text(_publisher!.description).padding(horizontal: 8), | ||||
|                             const Gap(12), | ||||
|                             Column( | ||||
|                               children: [ | ||||
| @@ -335,10 +330,8 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                                   children: [ | ||||
|                                     const Icon(Symbols.calendar_add_on), | ||||
|                                     const Gap(8), | ||||
|                                     Text('publisherJoinedAt').tr(args: [ | ||||
|                                       DateFormat('y/M/d') | ||||
|                                           .format(_publisher!.createdAt) | ||||
|                                     ]), | ||||
|                                     Text('publisherJoinedAt') | ||||
|                                         .tr(args: [DateFormat('y/M/d').format(_publisher!.createdAt)]), | ||||
|                                   ], | ||||
|                                 ), | ||||
|                                 Row( | ||||
| @@ -346,11 +339,30 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                                     const Icon(Symbols.trending_up), | ||||
|                                     const Gap(8), | ||||
|                                     Text('publisherSocialPointTotal').plural( | ||||
|                                       _publisher!.totalUpvote - | ||||
|                                           _publisher!.totalDownvote, | ||||
|                                       _publisher!.totalUpvote - _publisher!.totalDownvote, | ||||
|                                     ), | ||||
|                                   ], | ||||
|                                 ), | ||||
|                                 if (_realm != null) | ||||
|                                   Row( | ||||
|                                     children: [ | ||||
|                                       const Icon(Symbols.group_work), | ||||
|                                       const Gap(8), | ||||
|                                       InkWell( | ||||
|                                         child: Text('publisherAffiliatedBy').tr(args: [ | ||||
|                                           '@${_realm?.alias ?? 'unknown'}', | ||||
|                                         ]), | ||||
|                                         onTap: () { | ||||
|                                           GoRouter.of(context).pushNamed( | ||||
|                                             'realmDetail', | ||||
|                                             pathParameters: {'alias': _realm!.alias}, | ||||
|                                           ); | ||||
|                                         }, | ||||
|                                       ), | ||||
|                                       const Gap(8), | ||||
|                                       AccountImage(content: _realm?.avatar, radius: 8), | ||||
|                                     ], | ||||
|                                   ), | ||||
|                                 Row( | ||||
|                                   children: [ | ||||
|                                     const Icon(Symbols.tools_wrench), | ||||
| @@ -369,8 +381,7 @@ class _PostPublisherScreenState extends State<PostPublisherScreen> | ||||
|                                       }, | ||||
|                                     ), | ||||
|                                     const Gap(8), | ||||
|                                     AccountImage( | ||||
|                                         content: _account?.avatar, radius: 8), | ||||
|                                     AccountImage(content: _account?.avatar, radius: 8), | ||||
|                                   ], | ||||
|                                 ), | ||||
|                               ], | ||||
| @@ -447,6 +458,7 @@ class _PublisherPostList extends StatelessWidget { | ||||
|   final void Function() fetchPosts; | ||||
|   final void Function(int index, SnPost data) onChanged; | ||||
|   final void Function() onDeleted; | ||||
|  | ||||
|   const _PublisherPostList({ | ||||
|     super.key, | ||||
|     required this.isBusy, | ||||
|   | ||||
| @@ -6,16 +6,15 @@ import 'package:material_symbols_icons/symbols.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| import 'package:styled_widget/styled_widget.dart'; | ||||
| import 'package:surface/providers/sn_network.dart'; | ||||
| import 'package:surface/providers/userinfo.dart'; | ||||
| import 'package:surface/types/realm.dart'; | ||||
| import 'package:surface/widgets/account/account_image.dart'; | ||||
| import 'package:surface/widgets/app_bar_leading.dart'; | ||||
| import 'package:surface/widgets/dialog.dart'; | ||||
| import 'package:surface/widgets/loading_indicator.dart'; | ||||
| import 'package:surface/widgets/unauthorized_hint.dart'; | ||||
| import 'package:surface/widgets/universal_image.dart'; | ||||
|  | ||||
| import '../providers/userinfo.dart'; | ||||
| import '../widgets/unauthorized_hint.dart'; | ||||
|  | ||||
| class RealmScreen extends StatefulWidget { | ||||
|   const RealmScreen({super.key}); | ||||
|  | ||||
| @@ -101,9 +100,7 @@ class _RealmScreenState extends State<RealmScreen> { | ||||
|         title: Text('screenRealm').tr(), | ||||
|         actions: [ | ||||
|           IconButton( | ||||
|             icon: !_isCompactView | ||||
|                 ? const Icon(Symbols.view_list) | ||||
|                 : const Icon(Symbols.view_module), | ||||
|             icon: !_isCompactView ? const Icon(Symbols.view_list) : const Icon(Symbols.view_module), | ||||
|             onPressed: () { | ||||
|               setState(() => _isCompactView = !_isCompactView); | ||||
|             }, | ||||
| @@ -129,8 +126,7 @@ class _RealmScreenState extends State<RealmScreen> { | ||||
|                   final realm = _realms![idx]; | ||||
|                   if (_isCompactView) { | ||||
|                     return ListTile( | ||||
|                       contentPadding: | ||||
|                           const EdgeInsets.symmetric(horizontal: 16), | ||||
|                       contentPadding: const EdgeInsets.symmetric(horizontal: 16), | ||||
|                       leading: AccountImage( | ||||
|                         content: realm.avatar, | ||||
|                         fallbackWidget: const Icon(Symbols.group, size: 20), | ||||
| @@ -201,9 +197,7 @@ class _RealmScreenState extends State<RealmScreen> { | ||||
|                                 fit: StackFit.expand, | ||||
|                                 children: [ | ||||
|                                   Container( | ||||
|                                     color: Theme.of(context) | ||||
|                                         .colorScheme | ||||
|                                         .surfaceContainer, | ||||
|                                     color: Theme.of(context).colorScheme.surfaceContainer, | ||||
|                                     child: (realm.banner?.isEmpty ?? true) | ||||
|                                         ? const SizedBox.shrink() | ||||
|                                         : AutoResizeUniversalImage( | ||||
| @@ -217,8 +211,7 @@ class _RealmScreenState extends State<RealmScreen> { | ||||
|                                     child: AccountImage( | ||||
|                                       content: realm.avatar, | ||||
|                                       radius: 24, | ||||
|                                       fallbackWidget: | ||||
|                                           const Icon(Symbols.group, size: 24), | ||||
|                                       fallbackWidget: const Icon(Symbols.group, size: 24), | ||||
|                                     ), | ||||
|                                   ), | ||||
|                                 ], | ||||
| @@ -228,10 +221,8 @@ class _RealmScreenState extends State<RealmScreen> { | ||||
|                             Column( | ||||
|                               crossAxisAlignment: CrossAxisAlignment.start, | ||||
|                               children: [ | ||||
|                                 Text(realm.name).textStyle( | ||||
|                                     Theme.of(context).textTheme.titleMedium!), | ||||
|                                 Text(realm.description).textStyle( | ||||
|                                     Theme.of(context).textTheme.bodySmall!), | ||||
|                                 Text(realm.name).textStyle(Theme.of(context).textTheme.titleMedium!), | ||||
|                                 Text(realm.description).textStyle(Theme.of(context).textTheme.bodySmall!), | ||||
|                               ], | ||||
|                             ).padding(horizontal: 24, bottom: 14), | ||||
|                           ], | ||||
|   | ||||
| @@ -13,8 +13,11 @@ import 'package:surface/widgets/account/account_image.dart'; | ||||
| import 'package:surface/widgets/dialog.dart'; | ||||
| import 'package:very_good_infinite_list/very_good_infinite_list.dart'; | ||||
|  | ||||
| import '../../types/post.dart'; | ||||
|  | ||||
| class RealmDetailScreen extends StatefulWidget { | ||||
|   final String alias; | ||||
|  | ||||
|   const RealmDetailScreen({super.key, required this.alias}); | ||||
|  | ||||
|   @override | ||||
| @@ -32,6 +35,24 @@ class _RealmDetailScreenState extends State<RealmDetailScreen> { | ||||
|     } catch (err) { | ||||
|       if (!mounted) return; | ||||
|       context.showErrorDialog(err); | ||||
|       rethrow; | ||||
|     } finally { | ||||
|       setState(() {}); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   List<SnPublisher>? _publishers; | ||||
|  | ||||
|   Future<void> _fetchPublishers() async { | ||||
|     try { | ||||
|       final sn = context.read<SnNetworkProvider>(); | ||||
|       final resp = await sn.client.get('/cgi/co/publishers?realm=${widget.alias}'); | ||||
|       _publishers = List<SnPublisher>.from( | ||||
|         resp.data?.map((e) => SnPublisher.fromJson(e)) ?? [], | ||||
|       ); | ||||
|     } catch (err) { | ||||
|       if (mounted) context.showErrorDialog(err); | ||||
|       rethrow; | ||||
|     } finally { | ||||
|       setState(() {}); | ||||
|     } | ||||
| @@ -40,7 +61,9 @@ class _RealmDetailScreenState extends State<RealmDetailScreen> { | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _fetchRealm(); | ||||
|     _fetchRealm().then((_) { | ||||
|       _fetchPublishers(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
| @@ -60,8 +83,7 @@ class _RealmDetailScreenState extends State<RealmDetailScreen> { | ||||
|                 // scroll view thinks it has not been scrolled. | ||||
|                 // This is not necessary if the "headerSliverBuilder" only builds | ||||
|                 // widgets that do not overlap the next sliver. | ||||
|                 handle: | ||||
|                     NestedScrollView.sliverOverlapAbsorberHandleFor(context), | ||||
|                 handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), | ||||
|                 sliver: SliverAppBar( | ||||
|                   title: Text(_realm?.name ?? 'loading'.tr()), | ||||
|                   bottom: TabBar( | ||||
| @@ -77,7 +99,7 @@ class _RealmDetailScreenState extends State<RealmDetailScreen> { | ||||
|           }, | ||||
|           body: TabBarView( | ||||
|             children: [ | ||||
|               _RealmDetailHomeWidget(realm: _realm), | ||||
|               _RealmDetailHomeWidget(realm: _realm, publishers: _publishers), | ||||
|               _RealmMemberListWidget(realm: _realm), | ||||
|               _RealmSettingsWidget( | ||||
|                 realm: _realm, | ||||
| @@ -95,7 +117,9 @@ class _RealmDetailScreenState extends State<RealmDetailScreen> { | ||||
|  | ||||
| class _RealmDetailHomeWidget extends StatelessWidget { | ||||
|   final SnRealm? realm; | ||||
|   const _RealmDetailHomeWidget({super.key, required this.realm}); | ||||
|   final List<SnPublisher>? publishers; | ||||
|  | ||||
|   const _RealmDetailHomeWidget({super.key, required this.realm, this.publishers}); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
| @@ -118,6 +142,31 @@ class _RealmDetailHomeWidget extends StatelessWidget { | ||||
|           ).padding(horizontal: 24), | ||||
|         const Gap(16), | ||||
|         const Divider(), | ||||
|         Expanded( | ||||
|           child: ListView.builder( | ||||
|             padding: EdgeInsets.zero, | ||||
|             itemCount: publishers?.length ?? 0, | ||||
|             itemBuilder: (context, idx) { | ||||
|               final ele = publishers![idx]; | ||||
|               return ListTile( | ||||
|                 contentPadding: const EdgeInsets.symmetric(horizontal: 24), | ||||
|                 leading: AccountImage( | ||||
|                   content: ele.avatar, | ||||
|                   fallbackWidget: const Icon(Symbols.group, size: 24), | ||||
|                 ), | ||||
|                 title: Text(ele.nick), | ||||
|                 subtitle: Text('@${ele.name}'), | ||||
|                 trailing: const Icon(Symbols.chevron_right), | ||||
|                 onTap: () { | ||||
|                   GoRouter.of(context).pushNamed( | ||||
|                     'postPublisher', | ||||
|                     pathParameters: {'name': ele.name}, | ||||
|                   ); | ||||
|                 }, | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
|         ), | ||||
|       ], | ||||
|     ); | ||||
|   } | ||||
| @@ -125,6 +174,7 @@ class _RealmDetailHomeWidget extends StatelessWidget { | ||||
|  | ||||
| class _RealmMemberListWidget extends StatefulWidget { | ||||
|   final SnRealm? realm; | ||||
|  | ||||
|   const _RealmMemberListWidget({super.key, this.realm}); | ||||
|  | ||||
|   @override | ||||
| @@ -143,12 +193,10 @@ class _RealmMemberListWidgetState extends State<_RealmMemberListWidget> { | ||||
|     try { | ||||
|       final ud = context.read<UserDirectoryProvider>(); | ||||
|       final sn = context.read<SnNetworkProvider>(); | ||||
|       final resp = await sn.client.get( | ||||
|           '/cgi/id/realms/${widget.realm!.alias}/members', | ||||
|           queryParameters: { | ||||
|             'take': 10, | ||||
|             'offset': 0, | ||||
|           }); | ||||
|       final resp = await sn.client.get('/cgi/id/realms/${widget.realm!.alias}/members', queryParameters: { | ||||
|         'take': 10, | ||||
|         'offset': 0, | ||||
|       }); | ||||
|  | ||||
|       final out = List<SnRealmMember>.from( | ||||
|         resp.data['data']?.map((e) => SnRealmMember.fromJson(e)) ?? [], | ||||
| @@ -236,12 +284,10 @@ class _RealmMemberListWidgetState extends State<_RealmMemberListWidget> { | ||||
|                 fallbackWidget: const Icon(Symbols.group, size: 24), | ||||
|               ), | ||||
|               title: Text( | ||||
|                 ud.getAccountFromCache(member.accountId)?.nick ?? | ||||
|                     'unknown'.tr(), | ||||
|                 ud.getAccountFromCache(member.accountId)?.nick ?? 'unknown'.tr(), | ||||
|               ), | ||||
|               subtitle: Text( | ||||
|                 ud.getAccountFromCache(member.accountId)?.name ?? | ||||
|                     'unknown'.tr(), | ||||
|                 ud.getAccountFromCache(member.accountId)?.name ?? 'unknown'.tr(), | ||||
|               ), | ||||
|               trailing: IconButton( | ||||
|                 icon: const Icon(Symbols.person_remove), | ||||
| @@ -257,6 +303,7 @@ class _RealmMemberListWidgetState extends State<_RealmMemberListWidget> { | ||||
|  | ||||
| class _NewRealmMemberWidget extends StatefulWidget { | ||||
|   final SnRealm realm; | ||||
|  | ||||
|   const _NewRealmMemberWidget({super.key, required this.realm}); | ||||
|  | ||||
|   @override | ||||
| @@ -321,8 +368,7 @@ class _NewRealmMemberWidgetState extends State<_NewRealmMemberWidget> { | ||||
|               child: IconButton( | ||||
|                 onPressed: _isBusy ? null : () => _performAction(), | ||||
|                 icon: Icon(Symbols.send), | ||||
|                 visualDensity: | ||||
|                     const VisualDensity(horizontal: -4, vertical: -4), | ||||
|                 visualDensity: const VisualDensity(horizontal: -4, vertical: -4), | ||||
|                 padding: EdgeInsets.zero, | ||||
|               ), | ||||
|             ), | ||||
| @@ -337,8 +383,8 @@ class _NewRealmMemberWidgetState extends State<_NewRealmMemberWidget> { | ||||
| class _RealmSettingsWidget extends StatefulWidget { | ||||
|   final SnRealm? realm; | ||||
|   final Function() onUpdate; | ||||
|   const _RealmSettingsWidget( | ||||
|       {super.key, required this.realm, required this.onUpdate}); | ||||
|  | ||||
|   const _RealmSettingsWidget({super.key, required this.realm, required this.onUpdate}); | ||||
|  | ||||
|   @override | ||||
|   State<_RealmSettingsWidget> createState() => _RealmSettingsWidgetState(); | ||||
| @@ -382,6 +428,7 @@ class _RealmSettingsWidgetState extends State<_RealmSettingsWidget> { | ||||
|  | ||||
|     return Column( | ||||
|       children: [ | ||||
|         const Gap(16), | ||||
|         ListTile( | ||||
|           leading: const Icon(Symbols.edit), | ||||
|           trailing: const Icon(Symbols.chevron_right), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user