mirror of
https://github.com/nostrlabs-io/zap-stream-flutter.git
synced 2025-06-15 11:48:21 +00:00
@ -10,6 +10,7 @@ import 'package:zap_stream_flutter/utils.dart';
|
||||
import 'package:zap_stream_flutter/widgets/avatar.dart';
|
||||
import 'package:zap_stream_flutter/widgets/button.dart';
|
||||
import 'package:zap_stream_flutter/widgets/header.dart';
|
||||
import 'package:zap_stream_flutter/widgets/nostr_text.dart';
|
||||
import 'package:zap_stream_flutter/widgets/profile.dart';
|
||||
import 'package:zap_stream_flutter/widgets/stream_grid.dart';
|
||||
|
||||
@ -53,9 +54,15 @@ class ProfilePage extends StatelessWidget {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
profile.about ?? "",
|
||||
style: TextStyle(color: LAYER_5),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
style: TextStyle(color: LAYER_5),
|
||||
children: textToSpans(
|
||||
profile.about ?? "",
|
||||
[],
|
||||
profile.pubKey,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -101,7 +101,10 @@ class _StreamPage extends State<StreamPage> {
|
||||
aspectRatio: 16 / 9,
|
||||
child:
|
||||
_chewieController != null
|
||||
? Chewie(controller: _chewieController!)
|
||||
? Chewie(
|
||||
key: Key("stream:player:${stream.aTag}"),
|
||||
controller: _chewieController!,
|
||||
)
|
||||
: Container(
|
||||
color: LAYER_1,
|
||||
child:
|
||||
@ -163,9 +166,8 @@ class _StreamPage extends State<StreamPage> {
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showModalBottomSheet(
|
||||
showBottomSheet(
|
||||
context: context,
|
||||
constraints: BoxConstraints.expand(),
|
||||
builder: (context) => StreamInfoWidget(stream: stream),
|
||||
);
|
||||
},
|
||||
|
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));
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import 'package:intl/intl.dart';
|
||||
import 'package:zap_stream_flutter/theme.dart';
|
||||
import 'package:zap_stream_flutter/utils.dart';
|
||||
import 'package:zap_stream_flutter/widgets/profile.dart';
|
||||
import 'package:zap_stream_flutter/widgets/stream_cards.dart';
|
||||
|
||||
class StreamInfoWidget extends StatelessWidget {
|
||||
final StreamEvent stream;
|
||||
@ -38,6 +39,7 @@ class StreamInfoWidget extends StatelessWidget {
|
||||
),
|
||||
if (stream.info.summary?.isNotEmpty ?? false)
|
||||
Text(stream.info.summary!),
|
||||
StreamCardsWidget(stream: stream),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
18
pubspec.lock
18
pubspec.lock
@ -294,6 +294,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
flutter_markdown_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_markdown_plus
|
||||
sha256: fe74214c5ac2f850d93efda290dcde3f18006e90a87caa9e3e6c13222a5db4de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -544,6 +552,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
markdown:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: markdown
|
||||
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1210,4 +1226,4 @@ packages:
|
||||
version: "1.2.0"
|
||||
sdks:
|
||||
dart: ">=3.7.2 <4.0.0"
|
||||
flutter: ">=3.27.0"
|
||||
flutter: ">=3.27.1"
|
||||
|
@ -32,6 +32,7 @@ dependencies:
|
||||
emoji_picker_flutter: ^4.3.0
|
||||
bech32: ^0.2.2
|
||||
intl: ^0.20.2
|
||||
flutter_markdown_plus: ^1.0.3
|
||||
|
||||
dependency_overrides:
|
||||
ndk:
|
||||
|
Reference in New Issue
Block a user