relatica/lib/controls/timeline/status_header_control.dart

186 lines
6.3 KiB
Dart
Raw Normal View History

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
2023-03-12 01:50:31 +00:00
import 'package:logging/logging.dart';
import '../../globals.dart';
import '../../models/connection.dart';
import '../../models/timeline_entry.dart';
2023-11-18 03:47:38 +00:00
import '../../models/visibility.dart' as v;
import '../../routes.dart';
import '../../services/auth_service.dart';
import '../../services/connections_manager.dart';
import '../../services/reshared_via_service.dart';
2023-03-14 03:49:52 +00:00
import '../../utils/active_profile_selector.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 StatelessWidget {
2023-03-12 01:50:31 +00:00
static final _logger = Logger('$StatusHeaderControl');
final TimelineEntry entry;
2023-03-22 04:16:23 +00:00
final bool showIsCommentText;
const StatusHeaderControl({
super.key,
required this.entry,
2023-03-22 04:16:23 +00:00
this.showIsCommentText = false,
});
2022-12-28 03:54:33 +00:00
void goToProfile(BuildContext context, String id) {
context.pushNamed(ScreenPaths.userProfile, pathParameters: {'id': id});
}
@override
Widget build(BuildContext context) {
2023-03-12 01:50:31 +00:00
late final Connection author;
late final Connection reshareAuthor;
final activeProfile = getIt<AccountsService>().currentProfile;
final reshareId = getIt<ActiveProfileSelector<ReshareViaService>>()
.getForProfile(activeProfile)
.transform((s) => s.getForPost(entry.id)?.resharers.firstOrNull)
.getValueOrElse(() => null);
2023-11-18 03:47:38 +00:00
final manager = getIt<ActiveProfileSelector<ConnectionsManager>>()
.getForProfile(activeProfile)
2023-11-18 03:47:38 +00:00
.fold(
onSuccess: (m) => m,
onError: (error) {
_logger.severe('Error getting connection manager: $error');
return null;
});
author = manager!.getById(entry.authorId).getValueOrElse(
() => Connection(),
);
reshareAuthor = reshareId == null
? Connection()
: manager.getById(reshareId).getValueOrElse(
() => Connection(),
);
2022-12-28 03:54:33 +00:00
2023-03-20 02:16:30 +00:00
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
2023-03-20 02:16:30 +00:00
Wrap(
crossAxisAlignment: WrapCrossAlignment.end,
runSpacing: 5.0,
children: [
2023-03-20 02:16:30 +00:00
ImageControl(
imageUrl: author.avatarUrl.toString(),
iconOverride: const Icon(Icons.person),
2023-03-20 02:16:30 +00:00
width: 32.0,
2022-12-28 03:54:33 +00:00
onTap: () => goToProfile(context, author.id),
),
2023-03-20 02:16:30 +00:00
const HorizontalPadding(),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
2023-03-20 02:16:30 +00:00
GestureDetector(
onTap: () => goToProfile(context, author.id),
child: Text(
author.name,
style: Theme.of(context).textTheme.bodyLarge,
2023-03-20 02:16:30 +00:00
),
),
],
),
if (reshareAuthor.isNotEmpty &&
author.id != activeProfile.userId) ...[
2023-03-20 02:16:30 +00:00
const HorizontalPadding(width: 3.0),
const Text('reshared by '),
2023-03-20 02:16:30 +00:00
const HorizontalPadding(width: 3.0),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ImageControl(
imageUrl: reshareAuthor.avatarUrl.toString(),
iconOverride: const Icon(Icons.person),
2023-03-20 02:16:30 +00:00
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,
2023-03-20 02:16:30 +00:00
),
),
],
),
],
2023-03-22 04:16:23 +00:00
if (showIsCommentText && entry.parentId.isNotEmpty)
Text(
' ...made a comment:',
style: Theme.of(context).textTheme.bodyLarge,
2023-03-22 04:16:23 +00:00
),
],
),
2023-03-20 02:16:30 +00:00
Row(
children: [
Text(
ElapsedDateUtils.elapsedTimeStringFromEpochSeconds(
entry.backdatedTimestamp),
style: Theme.of(context).textTheme.bodySmall,
2023-03-20 02:16:30 +00:00
),
2023-11-18 03:47:38 +00:00
IconButton(
tooltip:
'Visibility: ${entry.visibility.type.toLabel()} (click for details)',
2023-11-18 03:47:38 +00:00
onPressed: () async {
await showVisibilityDialog(context, manager, entry.visibility);
2023-11-18 03:47:38 +00:00
},
icon: Icon(
switch (entry.visibility.type) {
v.VisibilityType.public => Icons.public,
v.VisibilityType.private => Icons.lock,
v.VisibilityType.unlisted => Icons.not_interested,
},
2023-11-18 03:47:38 +00:00
color: Theme.of(context).hintColor,
size: Theme.of(context).textTheme.bodySmall?.fontSize,
),
2022-12-28 03:54:33 +00:00
),
TimelineNetworkInfoControl(info: entry.networkInfo),
if (entry.deliveryData.hasDeliveryData) ...[
const HorizontalPadding(),
buildDeliveryIndicator(context),
],
2023-03-20 02:16:30 +00:00
],
),
],
);
}
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'),
),
),
);
}
}