💄 Collspible link embeds
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:island/models/embed.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:island/utils/mapping.dart';
|
||||
import 'package:island/widgets/content/embed/link.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';
|
||||
|
||||
class EmbedListWidget extends StatelessWidget {
|
||||
@@ -26,27 +24,73 @@ class EmbedListWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children:
|
||||
final normalizedEmbeds =
|
||||
embeds
|
||||
.map((embedData) => convertMapKeysToSnakeCase(embedData))
|
||||
.map(
|
||||
(embedData) => switch (embedData['type']) {
|
||||
'link' => EmbedLinkWidget(
|
||||
link: SnScrappedLink.fromJson(embedData),
|
||||
maxWidth:
|
||||
maxWidth ??
|
||||
math.min(
|
||||
MediaQuery.of(context).size.width,
|
||||
kWideScreenWidth,
|
||||
),
|
||||
.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: [
|
||||
if (linkEmbeds.isNotEmpty)
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
top: 8,
|
||||
left: renderingPadding.horizontal,
|
||||
right: renderingPadding.horizontal,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Theme.of(context).dividerColor),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Theme(
|
||||
data: Theme.of(
|
||||
context,
|
||||
).copyWith(dividerColor: Colors.transparent),
|
||||
child: ExpansionTile(
|
||||
initiallyExpanded: true,
|
||||
dense: true,
|
||||
leading: const Icon(Symbols.link),
|
||||
title: Text('${linkEmbeds.length} links'),
|
||||
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(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
...otherEmbeds.map(
|
||||
(embedData) => switch (embedData['type']) {
|
||||
'poll' => Card(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: renderingPadding.horizontal,
|
||||
@@ -64,8 +108,8 @@ class EmbedListWidget extends StatelessWidget {
|
||||
),
|
||||
_ => Text('Unable show embed: ${embedData['type']}'),
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user