💄 Collspible link embeds

This commit is contained in:
2025-11-16 18:23:24 +08:00
parent d94f8d004f
commit a8617a5040

View File

@@ -1,11 +1,9 @@
import 'dart:math' as math;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:island/models/embed.dart'; import 'package:island/models/embed.dart';
import 'package:island/services/responsive.dart';
import 'package:island/utils/mapping.dart'; import 'package:island/utils/mapping.dart';
import 'package:island/widgets/content/embed/link.dart'; import 'package:island/widgets/content/embed/link.dart';
import 'package:island/widgets/poll/poll_submit.dart'; import 'package:island/widgets/poll/poll_submit.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
class EmbedListWidget extends StatelessWidget { class EmbedListWidget extends StatelessWidget {
@@ -26,46 +24,92 @@ class EmbedListWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { 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();
return Column( return Column(
children: children: [
embeds if (linkEmbeds.isNotEmpty)
.map((embedData) => convertMapKeysToSnakeCase(embedData)) Container(
.map( margin: EdgeInsets.only(
(embedData) => switch (embedData['type']) { top: 8,
'link' => EmbedLinkWidget( left: renderingPadding.horizontal,
link: SnScrappedLink.fromJson(embedData), right: renderingPadding.horizontal,
maxWidth: ),
maxWidth ?? decoration: BoxDecoration(
math.min( border: Border.all(color: Theme.of(context).dividerColor),
MediaQuery.of(context).size.width, borderRadius: BorderRadius.circular(8),
kWideScreenWidth, ),
), child: Theme(
margin: EdgeInsets.only( data: Theme.of(
top: 4, context,
bottom: 4, ).copyWith(dividerColor: Colors.transparent),
left: renderingPadding.horizontal, child: ExpansionTile(
right: renderingPadding.horizontal, initiallyExpanded: true,
), dense: true,
), leading: const Icon(Symbols.link),
'poll' => Card( title: Text('${linkEmbeds.length} links'),
margin: EdgeInsets.symmetric( children: [
horizontal: renderingPadding.horizontal, Container(
vertical: 8, width: double.infinity,
), padding: const EdgeInsets.all(8),
child: child:
embedData['id'] == null linkEmbeds.length == 1
? const Text('Poll was unavailable...') ? EmbedLinkWidget(
: PollSubmit( link: SnScrappedLink.fromJson(linkEmbeds.first),
pollId: embedData['id'], )
onSubmit: (_) {}, : SingleChildScrollView(
isReadonly: !isInteractive, scrollDirection: Axis.horizontal,
isInitiallyExpanded: isFullPost, child: Row(
).padding(horizontal: 16, vertical: 12), children:
linkEmbeds
.map(
(embedData) => EmbedLinkWidget(
link: SnScrappedLink.fromJson(
embedData,
),
maxWidth:
200, // Fixed width for horizontal scroll
margin: const EdgeInsets.symmetric(
horizontal: 4,
),
),
)
.toList(),
),
),
), ),
_ => Text('Unable show embed: ${embedData['type']}'), ],
}, ),
) ),
.toList(), ),
...otherEmbeds.map(
(embedData) => switch (embedData['type']) {
'poll' => Card(
margin: EdgeInsets.symmetric(
horizontal: renderingPadding.horizontal,
vertical: 8,
),
child:
embedData['id'] == null
? const Text('Poll was unavailable...')
: PollSubmit(
pollId: embedData['id'],
onSubmit: (_) {},
isReadonly: !isInteractive,
isInitiallyExpanded: isFullPost,
).padding(horizontal: 16, vertical: 12),
),
_ => Text('Unable show embed: ${embedData['type']}'),
},
),
],
); );
} }
} }