💄 Optimize embed links

This commit is contained in:
2025-12-27 23:51:47 +08:00
parent a7c8a8d2ee
commit 56d1f14206
3 changed files with 70 additions and 67 deletions

View File

@@ -1542,5 +1542,9 @@
"settingsDefaultScreen": "Default Screen",
"notableDayChristmas": "Christmas",
"notableDayNewYear": "New Year",
"noSubscription": "No subscriptions"
"noSubscription": "No subscriptions",
"embedLinks": {
"one": "{} link",
"other": "{} links"
}
}

View File

@@ -1,3 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:island/models/embed.dart';
import 'package:island/utils/mapping.dart';
@@ -24,14 +25,15 @@ class EmbedListWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final normalizedEmbeds =
embeds
.map((e) => convertMapKeysToSnakeCase(e as Map<String, dynamic>))
.toList();
final linkEmbeds =
normalizedEmbeds.where((e) => e['type'] == 'link').toList();
final otherEmbeds =
normalizedEmbeds.where((e) => e['type'] != 'link').toList();
final normalizedEmbeds = embeds
.map((e) => convertMapKeysToSnakeCase(e as Map<String, dynamic>))
.toList();
final linkEmbeds = normalizedEmbeds
.where((e) => e['type'] == 'link')
.toList();
final otherEmbeds = normalizedEmbeds
.where((e) => e['type'] != 'link')
.toList();
return Column(
children: [
@@ -43,7 +45,9 @@ class EmbedListWidget extends StatelessWidget {
right: renderingPadding.horizontal,
),
decoration: BoxDecoration(
border: Border.all(color: Theme.of(context).dividerColor),
border: Border.all(
color: Theme.of(context).dividerColor.withOpacity(0.5),
),
borderRadius: BorderRadius.circular(8),
),
child: Theme(
@@ -54,36 +58,32 @@ class EmbedListWidget extends StatelessWidget {
initiallyExpanded: true,
dense: true,
leading: const Icon(Symbols.link),
title: Text('${linkEmbeds.length} links'),
title: Text('embedLinks'.plural(linkEmbeds.length)),
children: [
Container(
width: double.infinity,
padding: const EdgeInsets.all(8),
child:
linkEmbeds.length == 1
? EmbedLinkWidget(
link: SnScrappedLink.fromJson(linkEmbeds.first),
)
: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children:
linkEmbeds
.map(
(embedData) => EmbedLinkWidget(
link: SnScrappedLink.fromJson(
embedData,
),
maxWidth:
200, // Fixed width for horizontal scroll
margin: const EdgeInsets.symmetric(
horizontal: 4,
),
),
)
.toList(),
),
padding: const EdgeInsets.symmetric(horizontal: 8),
child: linkEmbeds.length == 1
? EmbedLinkWidget(
link: SnScrappedLink.fromJson(linkEmbeds.first),
)
: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: linkEmbeds
.map(
(embedData) => EmbedLinkWidget(
link: SnScrappedLink.fromJson(embedData),
maxWidth:
200, // Fixed width for horizontal scroll
margin: const EdgeInsets.symmetric(
horizontal: 4,
),
),
)
.toList(),
),
),
),
],
),
@@ -101,27 +101,26 @@ class EmbedListWidget extends StatelessWidget {
horizontal: 16,
vertical: 12,
),
child:
embedData['id'] == null
? const Text('Poll was unavailable...')
: PollSubmit(
pollId: embedData['id'],
onSubmit: (_) {},
isReadonly: !isInteractive,
isInitiallyExpanded: isFullPost,
),
child: embedData['id'] == null
? const Text('Poll was unavailable...')
: PollSubmit(
pollId: embedData['id'],
onSubmit: (_) {},
isReadonly: !isInteractive,
isInitiallyExpanded: isFullPost,
),
),
),
'fund' =>
embedData['id'] == null
? const Text('Fund envelope was unavailable...')
: FundEnvelopeWidget(
fundId: embedData['id'],
margin: EdgeInsets.symmetric(
horizontal: renderingPadding.horizontal,
vertical: 8,
fundId: embedData['id'],
margin: EdgeInsets.symmetric(
horizontal: renderingPadding.horizontal,
vertical: 8,
),
),
),
_ => Text('Unable show embed: ${embedData['type']}'),
},
),

View File

@@ -102,15 +102,13 @@ class _EmbedLinkWidgetState extends State<EmbedLinkWidget> {
children: [
// Sqaure open graph image
if (_isSquare == true) ...[
Flexible(
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 120),
child: AspectRatio(
aspectRatio: 1,
child: UniversalImage(
uri: widget.link.imageUrl!,
fit: BoxFit.cover,
),
ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 120),
child: AspectRatio(
aspectRatio: 1,
child: UniversalImage(
uri: widget.link.imageUrl!,
fit: BoxFit.cover,
),
),
),
@@ -127,8 +125,9 @@ class _EmbedLinkWidgetState extends State<EmbedLinkWidget> {
_isSquare != true)
Container(
width: double.infinity,
color:
Theme.of(context).colorScheme.surfaceContainerHigh,
color: Theme.of(
context,
).colorScheme.surfaceContainerHigh,
child: IntrinsicHeight(
child: UniversalImage(
uri: widget.link.imageUrl!,
@@ -154,12 +153,13 @@ class _EmbedLinkWidgetState extends State<EmbedLinkWidget> {
child: UniversalImage(
uri:
widget.link.faviconUrl!.startsWith('//')
? 'https:${widget.link.faviconUrl!}'
: widget.link.faviconUrl!
.startsWith('/')
? _getBaseUrl(widget.link.url) +
widget.link.faviconUrl!
: widget.link.faviconUrl!,
? 'https:${widget.link.faviconUrl!}'
: widget.link.faviconUrl!.startsWith(
'/',
)
? _getBaseUrl(widget.link.url) +
widget.link.faviconUrl!
: widget.link.faviconUrl!,
width: 16,
height: 16,
fit: BoxFit.cover,