import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../globals.dart'; import '../../models/connection.dart'; import '../../models/timeline_entry.dart'; import '../../models/visibility.dart' as v; import '../../riverpod_controllers/account_services.dart'; import '../../riverpod_controllers/connection_manager_services.dart'; import '../../riverpod_controllers/reshared_via_services.dart'; import '../../routes.dart'; import '../../utils/dateutils.dart'; import '../image_control.dart'; import '../padding.dart'; import '../visibility_dialog.dart'; import 'timeline_network_info_control.dart'; class StatusHeaderControl extends ConsumerWidget { final TimelineEntry entry; final bool showIsCommentText; const StatusHeaderControl({ super.key, required this.entry, this.showIsCommentText = false, }); void goToProfile(BuildContext context, String id) { context.pushNamed(ScreenPaths.userProfile, pathParameters: {'id': id}); } @override Widget build(BuildContext context, WidgetRef ref) { late final Connection author; late final Connection reshareAuthor; final profile = ref.watch(activeProfileProvider); final reshareId = ref.watch(resharedViaProvider(profile, entry.id)).resharers.firstOrNull; author = ref .watch(connectionByIdProvider(profile, entry.authorId)) .getValueOrElse( () => Connection(), ); reshareAuthor = reshareId == null ? Connection() : ref.watch(connectionByIdProvider(profile, reshareId)).getValueOrElse( () => Connection(), ); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Wrap( crossAxisAlignment: WrapCrossAlignment.end, runSpacing: 5.0, children: [ ImageControl( imageUrl: author.avatarUrl.toString(), iconOverride: const Icon(Icons.person), width: 32.0, onTap: () => goToProfile(context, author.id), ), const HorizontalPadding(), Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ GestureDetector( onTap: () => goToProfile(context, author.id), child: Text( author.name, style: Theme.of(context).textTheme.bodyLarge, ), ), ], ), if (reshareAuthor.isNotEmpty && author.id != profile.userId) ...[ const HorizontalPadding(width: 3.0), const Text('reshared by '), const HorizontalPadding(width: 3.0), Row( mainAxisSize: MainAxisSize.min, children: [ ImageControl( imageUrl: reshareAuthor.avatarUrl.toString(), iconOverride: const Icon(Icons.person), width: 32.0, onTap: () => goToProfile(context, reshareAuthor.id), ), const HorizontalPadding(width: 3.0), GestureDetector( onTap: () => goToProfile(context, reshareAuthor.id), child: Text( reshareAuthor.name, style: Theme.of(context).textTheme.bodyLarge, ), ), ], ), ], if (showIsCommentText && entry.parentId.isNotEmpty) Text( ' ...made a comment:', style: Theme.of(context).textTheme.bodyLarge, ), ], ), Row( children: [ Text( ElapsedDateUtils.elapsedTimeStringFromEpochSeconds( entry.backdatedTimestamp), style: Theme.of(context).textTheme.bodySmall, ), IconButton( tooltip: 'Visibility: ${entry.visibility.type.toLabel()} (click for details)', onPressed: () async { await showVisibilityDialog( context, ref, profile, entry.visibility); }, icon: Icon( switch (entry.visibility.type) { v.VisibilityType.public => Icons.public, v.VisibilityType.private => Icons.lock, v.VisibilityType.unlisted => Icons.not_interested, }, color: Theme.of(context).hintColor, size: Theme.of(context).textTheme.bodySmall?.fontSize, ), ), TimelineNetworkInfoControl(info: entry.networkInfo), if (entry.deliveryData.hasDeliveryData) ...[ const HorizontalPadding(), buildDeliveryIndicator(context), ], ], ), ], ); } Widget buildDeliveryIndicator(BuildContext context) { final data = entry.deliveryData; const fullyDeliveredIcon = '\uf1d8'; //fa-paper-plane const inDeliveryIcon = '\uf1d9'; //fa-paper-plane-o final percentRemaining = data.leftForDelivery.toDouble() / data.total.toDouble(); final iconText = percentRemaining > 0.1 ? inDeliveryIcon : fullyDeliveredIcon; return GestureDetector( onTap: () async { final text = """ Federated Messages Deliveries to Remote Servers Total: ${data.total} Completed: ${data.done} Failed: ${data.failed} Remaining: ${data.leftForDelivery} """; showConfirmDialog(context, text); }, child: Tooltip( message: 'Deliveries to remote servers: ${entry.deliveryData.done}/${entry.deliveryData.total}', child: Text( iconText, style: const TextStyle(fontFamily: 'ForkAwesome'), ), ), ); } }