import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart'; import '../../globals.dart'; import '../../models/timeline_entry.dart'; import '../../services/timeline_manager.dart'; import '../../utils/snackbar_builder.dart'; class InteractionsBarControl extends StatefulWidget { final TimelineEntry entry; final bool isMine; const InteractionsBarControl( {super.key, required this.entry, required this.isMine}); @override State createState() => _InteractionsBarControlState(); } class _InteractionsBarControlState extends State { static final _logger = Logger('$InteractionsBarControl'); var isProcessing = false; bool get isPost => widget.entry.parentId.isEmpty; bool get isFavorited => widget.entry.isFavorited; bool get isReshared => widget.entry.isReshare; int get reshares => widget.entry.engagementSummary.rebloggedCount; int get comments => widget.entry.engagementSummary.repliesCount; int get likes => widget.entry.engagementSummary.favoritesCount; Future toggleFavorited() async { setState(() { isProcessing = true; }); final newState = !isFavorited; _logger.finest('Trying to toggle favorite from $isFavorited to $newState'); final result = await getIt() .toggleFavorited(widget.entry.id, newState); result.match(onSuccess: (update) { setState(() { _logger.finest( 'Success toggling! $isFavorited -> ${update.entry.isFavorited}'); }); }, onError: (error) { buildSnackbar(context, 'Error toggling like status: $error'); }); setState(() { isProcessing = false; }); } Future resharePost() async { setState(() { isProcessing = true; }); final id = widget.entry.id; _logger.finest('Trying to reshare $id'); final result = await getIt().resharePost(id); result.match(onSuccess: (update) { setState(() { _logger.finest('Success resharing post by ${widget.entry.author}'); }); }, onError: (error) { buildSnackbar(context, 'Error resharing post by ${widget.entry.author}'); }); setState(() { isProcessing = false; }); } Future addComment() async { context.push('/comment/new?parent_id=${widget.entry.id}'); } Future deleteEntry() async { setState(() { isProcessing = true; }); final confirm = await showYesNoDialog(context, 'Delete ${isPost ? "Post" : "Comment"}'); if (confirm == true) { await getIt().deleteEntryById(widget.entry.id); } setState(() { isProcessing = false; }); } Future unResharePost() async { setState(() { isProcessing = true; }); final id = widget.entry.id; _logger.finest('Trying to un-reshare $id'); final result = await getIt().unResharePost(id); result.match(onSuccess: (update) { setState(() { _logger.finest('Success un-resharing post by ${widget.entry.author}'); }); }, onError: (error) { buildSnackbar( context, 'Error un-resharing post by ${widget.entry.author}'); }); setState(() { isProcessing = false; }); } @override Widget build(BuildContext context) { _logger.finest('Building: ${widget.entry.toShortString()}'); return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('$likes likes, $reshares reshares, $comments comments'), Row(children: [ IconButton( onPressed: isProcessing ? null : () async => await toggleFavorited(), icon: isFavorited ? const Icon( Icons.thumb_up, semanticLabel: 'Like', ) : Icon(Icons.thumb_up_outlined)), if (isPost) IconButton( onPressed: widget.isMine && !widget.entry.isReshare ? null : isProcessing ? null : () async => isReshared ? await unResharePost() : await resharePost(), icon: Icon(isReshared ? Icons.repeat_on_outlined : Icons.repeat)), IconButton( onPressed: isProcessing ? null : addComment, icon: Icon(Icons.add_comment)), if (widget.isMine && !widget.entry .isReshare) //TODO Figure out why reshares show up as mine sometimes but not others IconButton( onPressed: isProcessing ? null : () async => await deleteEntry(), icon: Icon(Icons.delete)) ]), ], ); } }