import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; import '../controls/padding.dart'; import '../models/connection.dart'; import '../services/connections_manager.dart'; class FollowRequestAdjudicationScreen extends StatefulWidget { final String userId; const FollowRequestAdjudicationScreen({super.key, required this.userId}); @override State createState() => _FollowRequestAdjudicationScreenState(); } class _FollowRequestAdjudicationScreenState extends State { var processing = false; @override Widget build(BuildContext context) { final manager = context.watch(); final connResult = manager.getById(widget.userId); late final Widget body; if (connResult.isFailure) { body = Text('Error getting contact information: ${connResult.error}'); } final contact = connResult.value; switch (contact.status) { case ConnectionStatus.theyFollowYou: case ConnectionStatus.youFollowThem: case ConnectionStatus.none: body = _buildMainPanel(context, manager, contact); break; case ConnectionStatus.mutual: body = const Text('Already allowed them to connect'); break; case ConnectionStatus.you: case ConnectionStatus.unknown: body = Text('Invalid state, nothing to do here: ${contact.status}'); break; } return Scaffold( appBar: AppBar( title: const Text( 'Accept Request?', )), body: Padding( padding: const EdgeInsets.all(8.0), child: Center(child: body), ), ); } Widget _buildMainPanel( BuildContext context, ConnectionsManager manager, Connection contact) { // Options are: // Accept and follow back // Accept and don't follow back // Reject // Back with no action // Calling method should check if completed (true) or not (false) to decide if updating their view of that item return Column( mainAxisAlignment: MainAxisAlignment.start, children: [ CachedNetworkImage(imageUrl: contact.avatarUrl.toString()), Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( contact.name, style: Theme.of(context).textTheme.titleLarge, ), const HorizontalPadding(), ], ), const VerticalPadding(), ElevatedButton( onPressed: processing ? null : () async => await accept(manager, contact, true), child: const Text('Accept and follow back'), ), const VerticalPadding(), ElevatedButton( onPressed: processing ? null : () async => accept(manager, contact, false), child: const Text("Accept but don't follow back"), ), const VerticalPadding(), ElevatedButton( onPressed: processing ? null : () async => reject(manager, contact), child: const Text('Reject'), ), const VerticalPadding(), ElevatedButton( onPressed: processing ? null : () async => ignore(manager, contact), child: const Text('Ignore (Rejects but user cannot ask again)'), ), ], ); } Future accept( ConnectionsManager manager, Connection contact, bool followBack, ) async { setState(() { processing = true; }); await manager.acceptFollowRequest(contact); if (followBack) { await manager.follow(contact); } setState(() { processing = false; }); if (mounted && context.canPop()) { context.pop(); } } Future reject(ConnectionsManager manager, Connection contact) async { setState(() { processing = true; }); await manager.rejectFollowRequest(contact); setState(() { processing = false; }); if (mounted && context.canPop()) { context.pop(); } } Future ignore(ConnectionsManager manager, Connection contact) async { setState(() { processing = true; }); await manager.ignoreFollowRequest(contact); setState(() { processing = false; }); if (mounted && context.canPop()) { context.pop(); } } }