♻️ Optimized fediverse post displaying
This commit is contained in:
parent
e44320e0fe
commit
65fe06de22
@ -1,25 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:html2md/html2md.dart' as html2md;
|
||||
import 'package:relative_time/relative_time.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:surface/types/post.dart';
|
||||
import 'package:html/parser.dart';
|
||||
import 'package:surface/widgets/account/account_image.dart';
|
||||
import 'package:surface/widgets/attachment/attachment_list.dart';
|
||||
import 'package:surface/widgets/html.dart';
|
||||
import 'package:surface/widgets/markdown_content.dart';
|
||||
import 'package:surface/widgets/universal_image.dart';
|
||||
|
||||
class FediversePostWidget extends StatelessWidget {
|
||||
final SnFediversePost data;
|
||||
final double maxWidth;
|
||||
const FediversePostWidget(
|
||||
{super.key, required this.data, required this.maxWidth});
|
||||
const FediversePostWidget({
|
||||
super.key,
|
||||
required this.data,
|
||||
required this.maxWidth,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final borderSide =
|
||||
BorderSide(width: 1, color: Theme.of(context).dividerColor);
|
||||
final backgroundColor = Theme.of(context).colorScheme.surfaceContainer;
|
||||
|
||||
return Center(
|
||||
child: Container(
|
||||
constraints: BoxConstraints(maxWidth: maxWidth),
|
||||
@ -30,8 +30,11 @@ class FediversePostWidget extends StatelessWidget {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
AccountImage(content: data.user.avatar),
|
||||
const Gap(8),
|
||||
AccountImage(
|
||||
content: data.user.avatar,
|
||||
radius: 20,
|
||||
),
|
||||
const Gap(12),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -40,66 +43,125 @@ class FediversePostWidget extends StatelessWidget {
|
||||
? data.user.nick
|
||||
: '@${data.user.name}',
|
||||
).bold(),
|
||||
Text(data.user.identifier),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
data.user.identifier.contains('@')
|
||||
? data.user.identifier
|
||||
: '${data.user.identifier}@${data.user.origin}',
|
||||
).fontSize(13),
|
||||
const Gap(4),
|
||||
Text(
|
||||
RelativeTime(context)
|
||||
.format(data.createdAt.toLocal()),
|
||||
).fontSize(13),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(8),
|
||||
...parseHtmlToWidgets(context, parse(data.content).children),
|
||||
).padding(horizontal: 12, vertical: 8),
|
||||
MarkdownTextContent(
|
||||
isAutoWarp: true,
|
||||
content: html2md.convert(data.content),
|
||||
).padding(horizontal: 16, bottom: 6),
|
||||
if (data.images.isNotEmpty)
|
||||
AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: ScrollConfiguration(
|
||||
behavior: AttachmentListScrollBehavior(),
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
itemCount: data.images.length,
|
||||
itemBuilder: (context, idx) {
|
||||
return Container(
|
||||
constraints: BoxConstraints(maxWidth: maxWidth),
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
border: Border(
|
||||
top: borderSide,
|
||||
bottom: borderSide,
|
||||
),
|
||||
borderRadius: AttachmentList.kDefaultRadius,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: AttachmentList.kDefaultRadius,
|
||||
child: AutoResizeUniversalImage(
|
||||
data.images[idx],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 8,
|
||||
bottom: 8,
|
||||
child: Chip(
|
||||
label: Text(
|
||||
'${idx + 1}/${data.images.length}'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => const Gap(8),
|
||||
physics: const BouncingScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
),
|
||||
),
|
||||
_FediversePostImageList(
|
||||
data: data,
|
||||
maxWidth: maxWidth,
|
||||
),
|
||||
],
|
||||
).padding(all: 8),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FediversePostImageList extends StatelessWidget {
|
||||
const _FediversePostImageList({
|
||||
required this.data,
|
||||
required this.maxWidth,
|
||||
});
|
||||
|
||||
final SnFediversePost data;
|
||||
final double maxWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final borderSide =
|
||||
BorderSide(width: 1, color: Theme.of(context).dividerColor);
|
||||
final backgroundColor = Theme.of(context).colorScheme.surfaceContainer;
|
||||
|
||||
if (data.images.length == 1) {
|
||||
return AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Container(
|
||||
constraints: BoxConstraints(maxWidth: maxWidth),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
border: Border(
|
||||
top: borderSide,
|
||||
bottom: borderSide,
|
||||
),
|
||||
borderRadius: AttachmentList.kDefaultRadius,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: AttachmentList.kDefaultRadius,
|
||||
child: AutoResizeUniversalImage(
|
||||
data.images.first,
|
||||
),
|
||||
),
|
||||
),
|
||||
).padding(horizontal: 8);
|
||||
}
|
||||
|
||||
return AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: ScrollConfiguration(
|
||||
behavior: AttachmentListScrollBehavior(),
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
itemCount: data.images.length,
|
||||
itemBuilder: (context, idx) {
|
||||
return Container(
|
||||
constraints: BoxConstraints(maxWidth: maxWidth),
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
border: Border(
|
||||
top: borderSide,
|
||||
bottom: borderSide,
|
||||
),
|
||||
borderRadius: AttachmentList.kDefaultRadius,
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: AttachmentList.kDefaultRadius,
|
||||
child: AutoResizeUniversalImage(
|
||||
data.images[idx],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 8,
|
||||
bottom: 8,
|
||||
child: Chip(
|
||||
label: Text('${idx + 1}/${data.images.length}'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => const Gap(8),
|
||||
physics: const BouncingScrollPhysics(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
52
pubspec.lock
52
pubspec.lock
@ -53,10 +53,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.0"
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -213,10 +213,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: chalkdart
|
||||
sha256: "08c910ee341fcdd1e46f20ddce59b13c1d85f5d97f2fd2f12014c46ede670e40"
|
||||
sha256: e7cfcc9a9d9546843304c1ff87fe0696c7eb82ee70e6df63f555f321b15a40d8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.3.3"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -301,10 +301,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: croppy
|
||||
sha256: "99f4fbb4a4b44d2712e8dcd61c57c1acac151bd53cab11de3babec80407ed266"
|
||||
sha256: "2a69059d9ec007b79d6a494854094b2e3c0a4f7ed609cf55a4805c9de9ec171d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.5"
|
||||
version: "1.3.6"
|
||||
cross_file:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -541,10 +541,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "7423298f08f6fc8cce05792bae329f9a93653fc9c08712831b1a55540127995d"
|
||||
sha256: "2458a41b4dc53899263bb16b17961797deaa18d4660e4d33e4de8a6c2a13db9c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.2"
|
||||
version: "9.0.3"
|
||||
file_saver:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -702,6 +702,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
flutter_blurhash:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_blurhash
|
||||
sha256: "5e67678e479ac639069d7af1e133f4a4702311491188ff3e0227486430db0c06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
flutter_cache_manager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -937,10 +945,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_webrtc
|
||||
sha256: "6ea3a86d95b61cfe42d5715426d355b3cece6c88d0119de428d56f6c653811ce"
|
||||
sha256: b832dc76c0d1577f14aaf35e9c38d4ed7667cbc89c492b7bf4505d8d5f62e08b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.11"
|
||||
version: "0.12.12+hotfix.1"
|
||||
freezed:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -1133,6 +1141,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.5"
|
||||
html2md:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: html2md
|
||||
sha256: "465cf8ffa1b510fe0e97941579bf5b22e2d575f2cecb500a9c0254efe33a8036"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1353,10 +1369,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: livekit_client
|
||||
sha256: "753bbf484c6b70f10f3dc1dc808dfe3755f472d80eb9682323cff07ad8e2609d"
|
||||
sha256: "7f489fa415253d8d99c649b7efc95a733c5e5ac38dcfb02362ced99feb139376"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
local_notifier:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1417,10 +1433,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: material_symbols_icons
|
||||
sha256: ca30ccbd97763353bde6bb1076aa4f4d17a40db0804384da77df142102aa225d
|
||||
sha256: ee916e08fc0e15d4544a3544b3a46821808b8c965629b56e076e4da1cfe69915
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2808.0"
|
||||
version: "4.2808.1"
|
||||
media_kit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1553,10 +1569,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67"
|
||||
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.2.0"
|
||||
package_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -2526,10 +2542,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: b89e6e24d1454e149ab20fbb225af58660f0c0bf4475544650700d8e2da54aef
|
||||
sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.11.0"
|
||||
version: "5.12.0"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -139,6 +139,8 @@ dependencies:
|
||||
geolocator: ^13.0.2
|
||||
fast_rsa: ^3.8.0
|
||||
flutter_card_swiper: ^7.0.2
|
||||
html2md: ^1.3.2
|
||||
flutter_blurhash: ^0.8.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Loading…
x
Reference in New Issue
Block a user