relatica/lib/controls/timeline/status_header_control.dart

176 wiersze
6.0 KiB
Dart

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'),
),
),
);
}
}