import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:nested/nested.dart'; import '../../../hooks/logged_in_action.dart'; import '../../../hooks/stores.dart'; import '../../../l10n/l10n_from_string.dart'; import '../../../stores/accounts_store.dart'; import '../../../util/async_store_listener.dart'; import '../../../util/mobx_provider.dart'; import '../../../util/observer_consumers.dart'; import '../../../widgets/pull_to_refresh.dart'; import 'block_dialog.dart'; import 'block_tile.dart'; import 'blocks_store.dart'; class BlocksPage extends HookWidget { const BlocksPage._(); @override Widget build(BuildContext context) { final accStore = useAccountsStore(); return DefaultTabController( length: accStore.loggedInInstances.length, child: Scaffold( appBar: AppBar( title: const Text('Blocks'), bottom: TabBar( isScrollable: true, tabs: [ for (final instance in accStore.loggedInInstances) Tab( child: Text( '${accStore.defaultUsernameFor(instance)!}@$instance'), ), ], ), ), body: TabBarView( children: [ for (final instance in accStore.loggedInInstances) _UserBlocksWrapper( instanceHost: instance, username: accStore.defaultUsernameFor(instance)!, ) ], ), ), ); } static Route route() => MaterialPageRoute(builder: (context) => const BlocksPage._()); } class _UserBlocksWrapper extends StatelessWidget { final String instanceHost; final String username; const _UserBlocksWrapper( {required this.instanceHost, required this.username}); @override Widget build(BuildContext context) { return MobxProvider( create: (context) => BlocksStore( instanceHost: instanceHost, token: context .read() .userDataFor(instanceHost, username)! .jwt, )..refresh(), child: const _UserBlocks(), ); } } class _UserBlocks extends HookWidget { const _UserBlocks(); @override Widget build(BuildContext context) { final loggedInAction = useLoggedInAction(context.read().instanceHost); return Nested( children: [ AsyncStoreListener( asyncStore: context.read().blocksState, ), AsyncStoreListener( asyncStore: context.read().communityBlockingState, ), AsyncStoreListener( asyncStore: context.read().userBlockingState, ), ], child: ObserverBuilder( builder: (context, store) { return PullToRefresh( onRefresh: store.refresh, child: ListView( children: [ if (!store.isUsable) ...[ if (store.blocksState.isLoading) const Padding( padding: EdgeInsets.only(top: 64), child: Center( child: CircularProgressIndicator.adaptive(), ), ) else if (store.blocksState.errorTerm != null) Padding( padding: const EdgeInsets.only(top: 64), child: Center( child: Text( store.blocksState.errorTerm!.tr(context), ), ), ) ] else ...[ for (final user in store.blockedUsers!) MobxProvider.value( value: user, key: ValueKey(user), child: const BlockPersonTile(), ), if (store.blockedUsers!.isEmpty) const ListTile( title: Center( child: Text('No users blocked'), ), ), ListTile( leading: Padding( padding: const EdgeInsets.only(left: 16, right: 10), child: store.userBlockingState.isLoading ? const CircularProgressIndicator.adaptive() : const Icon(Icons.add), ), onTap: store.userBlockingState.isLoading ? null : loggedInAction( (token) async { final person = await BlockPersonDialog.show(context); if (person != null) { await store.blockUser(token, person.person.id); } }, ), title: const Text('Block User'), ), const Divider(), for (final community in store.blockedCommunities!) MobxProvider.value( value: community, key: ValueKey(community), child: const BlockCommunityTile(), ), if (store.blockedCommunities!.isEmpty) const ListTile( title: Center( child: Text('No communities blocked'), ), ), ListTile( leading: Padding( padding: const EdgeInsets.only(left: 16, right: 10), child: store.communityBlockingState.isLoading ? const CircularProgressIndicator.adaptive() : const Icon(Icons.add), ), onTap: store.communityBlockingState.isLoading ? null : loggedInAction( (token) async { final community = await BlockCommunityDialog.show(context); if (community != null) { await store.blockCommunity( token, community.community.id, ); } }, ), title: const Text('Block Community'), ), ], ], ), ); }, ), ); } }