relatica/lib/controls/timeline/status_control.dart

189 wiersze
5.7 KiB
Dart

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../globals.dart';
import '../../models/attachment_media_type_enum.dart';
import '../../models/connection.dart';
import '../../models/entry_tree_item.dart';
import '../../models/timeline_entry.dart';
import '../../screens/image_viewer_screen.dart';
import '../../services/connections_manager.dart';
import '../../utils/dateutils.dart';
import '../../utils/snackbar_builder.dart';
import '../padding.dart';
import 'interactions_bar_control.dart';
class StatusControl extends StatelessWidget {
final EntryTreeItem item;
TimelineEntry get entry => item.entry;
const StatusControl({super.key, required this.item});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildHeader(context),
const VerticalPadding(
height: 5,
),
buildBody(context),
const VerticalPadding(
height: 5,
),
buildMediaBar(context),
const VerticalPadding(
height: 5,
),
InteractionsBarControl(entry: entry),
const VerticalPadding(
height: 5,
),
buildChildComments(context),
],
),
);
}
Widget buildHeader(BuildContext context) {
final author = getIt<ConnectionsManager>()
.getById(entry.authorId)
.getValueOrElse(() => Connection());
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CachedNetworkImage(
imageUrl: author.avatarUrl.toString(),
width: 32.0,
),
const HorizontalPadding(),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
author.name,
style: Theme.of(context).textTheme.bodyText1,
),
Text(
ElapsedDateUtils.epochSecondsToString(entry.backdatedTimestamp),
style: Theme.of(context).textTheme.caption,
),
],
),
],
);
}
Widget buildBody(BuildContext context) {
return HtmlWidget(
entry.body,
onTapUrl: (url) async {
final uri = Uri.tryParse(url);
if (uri == null) {
buildSnackbar(context, 'Bad link: $url');
return false;
}
if (await canLaunchUrl(uri)) {
buildSnackbar(
context,
'Attempting to launch video: $url',
);
await launchUrl(uri);
} else {
buildSnackbar(context, 'Unable to launch video: $url');
return false;
}
return true;
},
onTapImage: (imageMetadata) {
print(imageMetadata);
},
);
}
Widget buildMediaBar(BuildContext context) {
final items = entry.mediaAttachments;
if (items.isEmpty) {
return const SizedBox();
}
return SizedBox(
width: 250.0,
height: 250.0,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
final item = items[index];
if (item.explicitType == AttachmentMediaType.video) {
return ElevatedButton(
onPressed: () async {
if (await canLaunchUrl(item.uri)) {
buildSnackbar(
context,
'Attempting to launch video: ${item.uri}',
);
await launchUrl(item.uri);
} else {
buildSnackbar(
context, 'Unable to launch video: ${item.uri}');
}
},
child: Text(item.description.isNotEmpty
? item.description
: 'Video'));
}
if (item.explicitType != AttachmentMediaType.image) {
return Text('${item.explicitType}: ${item.uri}');
}
return InkWell(
onTap: () async {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ImageViewerScreen(attachment: item);
}));
},
child: CachedNetworkImage(
width: 250.0,
height: 250.0,
imageUrl: item.thumbnailUri.toString(),
),
);
// return Text(item.toString());
},
separatorBuilder: (context, index) {
return HorizontalPadding();
},
itemCount: items.length));
}
Widget buildChildComments(BuildContext context) {
final comments = item.children;
if (comments.isEmpty) {
return Text('No comments');
}
return Padding(
padding: EdgeInsets.only(left: 20.0, top: 5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.subdirectory_arrow_right),
Expanded(
child: Column(
children: comments.map((c) => StatusControl(item: c)).toList(),
),
),
],
));
}
}