mirror of
https://github.com/nostrlabs-io/zap-stream-flutter.git
synced 2025-06-16 20:08:50 +00:00
95
lib/widgets/stream_cards.dart
Normal file
95
lib/widgets/stream_cards.dart
Normal file
@ -0,0 +1,95 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_markdown_plus/flutter_markdown_plus.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:ndk/ndk.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:zap_stream_flutter/imgproxy.dart';
|
||||
import 'package:zap_stream_flutter/rx_filter.dart';
|
||||
import 'package:zap_stream_flutter/theme.dart';
|
||||
import 'package:zap_stream_flutter/utils.dart';
|
||||
import 'package:zap_stream_flutter/widgets/nostr_text.dart';
|
||||
|
||||
class StreamCardsWidget extends StatelessWidget {
|
||||
final StreamEvent stream;
|
||||
|
||||
const StreamCardsWidget({super.key, required this.stream});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RxFilter<Nip01Event>(
|
||||
Key("stream:cards:${stream.aTag}"),
|
||||
filters: [
|
||||
Filter(kinds: [17_777], authors: [stream.info.host], limit: 1),
|
||||
],
|
||||
builder: (context, state) {
|
||||
final cardList = state?.firstOrNull;
|
||||
if (cardList == null) return SizedBox();
|
||||
|
||||
final cardIds = cardList.getTags("a");
|
||||
return RxFilter<Nip01Event>(
|
||||
Key("stream:cards:${stream.aTag}:cards"),
|
||||
filters: [
|
||||
Filter(
|
||||
kinds: [37_777],
|
||||
authors: [stream.info.host],
|
||||
dTags: cardIds.map((i) => i.split(":").last).toList(),
|
||||
),
|
||||
],
|
||||
builder: (context, state) {
|
||||
final cards = state ?? [];
|
||||
|
||||
return Column(
|
||||
spacing: 8,
|
||||
children: cards.map((c) => _streamCard(context, c)).toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _streamCard(BuildContext context, Nip01Event card) {
|
||||
final title = card.getFirstTag("title") ?? card.getFirstTag("subject");
|
||||
final image = card.getFirstTag("image");
|
||||
final link = card.getFirstTag("r");
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(color: LAYER_2, borderRadius: DEFAULT_BR),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
if (title?.isNotEmpty ?? false)
|
||||
Text(
|
||||
title!,
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (image?.isNotEmpty ?? false)
|
||||
link != null
|
||||
? GestureDetector(
|
||||
onTap: () {
|
||||
launchUrl(Uri.parse(link));
|
||||
},
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, image!),
|
||||
errorWidget:
|
||||
(_, _, _) =>
|
||||
SvgPicture.asset("assets/svg/logo.svg", height: 40),
|
||||
),
|
||||
)
|
||||
: CachedNetworkImage(imageUrl: proxyImg(context, image!)),
|
||||
MarkdownBody(
|
||||
data: card.content,
|
||||
onTapLink: (text, href, title) {
|
||||
if (href != null) {
|
||||
launchUrl(Uri.parse(href));
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user