kopia lustrzana https://gitlab.com/mysocialportal/relatica
				
				
				
			
		
			
				
	
	
		
			222 wiersze
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			222 wiersze
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Dart
		
	
	
| 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/clipboard_utils.dart';
 | |
| import '../../utils/snackbar_builder.dart';
 | |
| import '../../utils/url_opening_utils.dart';
 | |
| 
 | |
| class InteractionsBarControl extends StatefulWidget {
 | |
|   final TimelineEntry entry;
 | |
|   final bool openRemote;
 | |
|   final bool showOpenControl;
 | |
|   final bool isMine;
 | |
| 
 | |
|   const InteractionsBarControl({
 | |
|     super.key,
 | |
|     required this.entry,
 | |
|     required this.isMine,
 | |
|     required this.showOpenControl,
 | |
|     required this.openRemote,
 | |
|   });
 | |
| 
 | |
|   @override
 | |
|   State<InteractionsBarControl> createState() => _InteractionsBarControlState();
 | |
| }
 | |
| 
 | |
| class _InteractionsBarControlState extends State<InteractionsBarControl> {
 | |
|   static final _logger = Logger('$InteractionsBarControl');
 | |
| 
 | |
|   var isProcessing = false;
 | |
| 
 | |
|   bool get isPost => widget.entry.parentId.isEmpty;
 | |
| 
 | |
|   bool get isFavorited => widget.entry.isFavorited;
 | |
| 
 | |
|   bool get youReshared => widget.entry.youReshared;
 | |
| 
 | |
|   int get reshares => widget.entry.engagementSummary.rebloggedCount;
 | |
| 
 | |
|   int get comments => widget.entry.engagementSummary.repliesCount;
 | |
| 
 | |
|   int get likes => widget.entry.engagementSummary.favoritesCount;
 | |
| 
 | |
|   Future<void> toggleFavorited() async {
 | |
|     setState(() {
 | |
|       isProcessing = true;
 | |
|     });
 | |
|     final newState = !isFavorited;
 | |
|     _logger.finest('Trying to toggle favorite from $isFavorited to $newState');
 | |
|     final result = await getIt<TimelineManager>()
 | |
|         .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<void> resharePost() async {
 | |
|     setState(() {
 | |
|       isProcessing = true;
 | |
|     });
 | |
|     final id = widget.entry.id;
 | |
|     _logger.finest('Trying to reshare $id');
 | |
|     final result = await getIt<TimelineManager>().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<void> addComment() async {
 | |
|     context.push('/comment/new?parent_id=${widget.entry.id}');
 | |
|   }
 | |
| 
 | |
|   Future<void> deleteEntry() async {
 | |
|     setState(() {
 | |
|       isProcessing = true;
 | |
|     });
 | |
|     final confirm =
 | |
|         await showYesNoDialog(context, 'Delete ${isPost ? "Post" : "Comment"}');
 | |
|     if (confirm == true) {
 | |
|       await getIt<TimelineManager>().deleteEntryById(widget.entry.id);
 | |
|     }
 | |
|     setState(() {
 | |
|       isProcessing = false;
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   Future<void> unResharePost() async {
 | |
|     setState(() {
 | |
|       isProcessing = true;
 | |
|     });
 | |
|     final id = widget.entry.id;
 | |
|     _logger.finest('Trying to un-reshare $id');
 | |
|     final result = await getIt<TimelineManager>().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;
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   Future<void> openAction(BuildContext context) async {
 | |
|     const goToPost = 'Go to Post';
 | |
|     const copyUrl = 'Copy URL';
 | |
|     const openExternal = 'Open In Browser';
 | |
|     final options = [
 | |
|       if (widget.showOpenControl && !widget.openRemote) goToPost,
 | |
|       openExternal,
 | |
|       copyUrl,
 | |
|       'Cancel'
 | |
|     ];
 | |
|     final result =
 | |
|         await showChooseOptions(context, 'Would you like to', options);
 | |
| 
 | |
|     if (!mounted) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (result) {
 | |
|       case goToPost:
 | |
|         context.push('/post/view/${widget.entry.id}/${widget.entry.id}');
 | |
|         break;
 | |
|       case openExternal:
 | |
|         await openUrlStringInSystembrowser(
 | |
|           context,
 | |
|           widget.entry.externalLink,
 | |
|           'Post',
 | |
|         );
 | |
|         break;
 | |
|       case copyUrl:
 | |
|         await copyToClipboard(
 | |
|           context: context,
 | |
|           text: widget.entry.externalLink,
 | |
|           message: 'Post link copied to clipboard',
 | |
|         );
 | |
|         break;
 | |
|       default:
 | |
|       //do nothing
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   @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.youReshared
 | |
|                     ? null
 | |
|                     : isProcessing
 | |
|                         ? null
 | |
|                         : () async => youReshared
 | |
|                             ? await unResharePost()
 | |
|                             : await resharePost(),
 | |
|                 icon: Icon(
 | |
|                     youReshared ? Icons.repeat_on_outlined : Icons.repeat)),
 | |
|           IconButton(
 | |
|               onPressed: isProcessing ? null : addComment,
 | |
|               icon: Icon(Icons.add_comment)),
 | |
|           if (widget.isMine &&
 | |
|               !widget.entry
 | |
|                   .youReshared) //TODO Figure out why reshares show up as mine sometimes but not others
 | |
|             IconButton(
 | |
|                 onPressed:
 | |
|                     isProcessing ? null : () async => await deleteEntry(),
 | |
|                 icon: Icon(Icons.delete)),
 | |
|           Expanded(
 | |
|             child: Row(
 | |
|               mainAxisAlignment: MainAxisAlignment.end,
 | |
|               children: [
 | |
|                 IconButton(
 | |
|                   onPressed: () async {
 | |
|                     await openAction(context);
 | |
|                   },
 | |
|                   icon: const Icon(Icons.launch),
 | |
|                 ),
 | |
|               ],
 | |
|             ),
 | |
|           ),
 | |
|         ]),
 | |
|       ],
 | |
|     );
 | |
|   }
 | |
| }
 |