import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:solian/models/reaction.dart'; import 'package:solian/providers/auth.dart'; import 'package:solian/utils/service_url.dart'; Future doReact( String dataset, int id, String symbol, int attitude, final void Function(String symbol, int num) onReact, BuildContext context, ) async { final auth = context.read(); if (!await auth.isAuthorized()) return; var uri = getRequestUri( 'interactive', '/api/p/$dataset/$id/react', ); var res = await auth.client!.post( uri, headers: { 'Content-Type': 'application/json', }, body: jsonEncode({ 'symbol': symbol, 'attitude': attitude, }), ); if (res.statusCode == 201) { onReact(symbol, 1); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Your reaction has been added onto this post."), ), ); } else if (res.statusCode == 204) { onReact(symbol, -1); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Your reaction has been removed from this post."), ), ); } else { var message = utf8.decode(res.bodyBytes); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Something went wrong... $message")), ); } if (Navigator.canPop(context)) { Navigator.pop(context); } } class ReactionActionPopup extends StatefulWidget { final String dataset; final int id; final void Function(String symbol, int num) onReact; const ReactionActionPopup({ super.key, required this.dataset, required this.id, required this.onReact, }); @override State createState() => _ReactionActionPopupState(); } class _ReactionActionPopupState extends State { bool _isSubmitting = false; Future doWidgetReact( String symbol, int attitude, BuildContext context, ) async { if (_isSubmitting) return; setState(() => _isSubmitting = true); await doReact( widget.dataset, widget.id, symbol, attitude, widget.onReact, context, ); setState(() => _isSubmitting = false); } @override Widget build(BuildContext context) { final reactEntries = reactions.entries.toList(); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.only(left: 8, right: 8, top: 20), child: Padding( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 12, ), child: Text( 'Add a reaction', style: Theme.of(context).textTheme.headlineSmall, ), ), ), _isSubmitting ? const LinearProgressIndicator() : Container(), Expanded( child: ListView.builder( itemCount: reactions.length, itemBuilder: (BuildContext context, int index) { var info = reactEntries[index]; return InkWell( onTap: () async { await doWidgetReact(info.key, info.value.attitude, context); }, child: ListTile( title: Text(info.value.icon), subtitle: Text( ":${info.key}:", style: const TextStyle(fontFamily: "monospace"), ), ), ); }, ), ), ], ); } }