mirror of
https://github.com/nostrlabs-io/zap-stream-flutter.git
synced 2025-06-15 11:48:21 +00:00
feat: badge awards
This commit is contained in:
@ -580,3 +580,8 @@ TLVEntity decodeBech32ToTLVEntity(String input) {
|
||||
return TLVEntity(data.hrp, [TLV(0, data8bit.length, data8bit)]);
|
||||
}
|
||||
}
|
||||
|
||||
Filter aTagToFilter(String tag) {
|
||||
final ts = tag.split(":");
|
||||
return Filter(kinds: [int.parse(ts[0])], authors: [ts[1]], dTags: [ts[2]]);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import 'package:zap_stream_flutter/main.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/chat_badge.dart';
|
||||
import 'package:zap_stream_flutter/widgets/chat_message.dart';
|
||||
import 'package:zap_stream_flutter/widgets/chat_raid.dart';
|
||||
import 'package:zap_stream_flutter/widgets/chat_write.dart';
|
||||
@ -27,6 +28,7 @@ class ChatWidget extends StatelessWidget {
|
||||
Filter(kinds: [1311, 9735], limit: 200, aTags: [stream.aTag]),
|
||||
Filter(kinds: [1312], limit: 200, aTags: [stream.aTag]),
|
||||
Filter(kinds: [Nip51List.kMute], authors: muteLists),
|
||||
Filter(kinds: [8], authors: [stream.info.host]),
|
||||
];
|
||||
return RxFilter<Nip01Event>(
|
||||
Key("stream:chat:${stream.aTag}"),
|
||||
@ -89,6 +91,10 @@ class ChatWidget extends StatelessWidget {
|
||||
stream: stream,
|
||||
zap: filteredChat[idx],
|
||||
),
|
||||
8 => ChatBadgeAwardWidget(
|
||||
event: filteredChat[idx],
|
||||
stream: stream,
|
||||
),
|
||||
_ => SizedBox(),
|
||||
},
|
||||
),
|
||||
|
74
lib/widgets/chat_badge.dart
Normal file
74
lib/widgets/chat_badge.dart
Normal file
@ -0,0 +1,74 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:ndk/entities.dart';
|
||||
import 'package:zap_stream_flutter/imgproxy.dart';
|
||||
import 'package:zap_stream_flutter/main.dart';
|
||||
import 'package:zap_stream_flutter/theme.dart';
|
||||
import 'package:zap_stream_flutter/utils.dart';
|
||||
import 'package:zap_stream_flutter/widgets/profile.dart';
|
||||
|
||||
class ChatBadgeAwardWidget extends StatelessWidget {
|
||||
final Nip01Event event;
|
||||
final StreamEvent stream;
|
||||
|
||||
const ChatBadgeAwardWidget({
|
||||
super.key,
|
||||
required this.event,
|
||||
required this.stream,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final aTag = event.getFirstTag("a");
|
||||
if (aTag == null) return SizedBox();
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 2, vertical: 4),
|
||||
padding: EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(color: LAYER_1, borderRadius: DEFAULT_BR),
|
||||
child: FutureBuilder(
|
||||
future: ndk.requests.query(filters: [aTagToFilter(aTag)]).future,
|
||||
builder: (context, state) {
|
||||
final badge = state.data?.firstOrNull;
|
||||
final image = badge?.getFirstTag("image");
|
||||
final name = badge?.getFirstTag("name");
|
||||
final title = badge?.getFirstTag("description");
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
if (image?.isNotEmpty ?? false)
|
||||
ProxyImg(url: image, width: 64),
|
||||
if (name?.isNotEmpty ?? false)
|
||||
Text(
|
||||
name!,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
if (title?.isNotEmpty ?? false)
|
||||
Text(
|
||||
title!,
|
||||
style: TextStyle(color: LAYER_5),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
"Awarded to: ",
|
||||
style: TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
...event
|
||||
.getTags("p")
|
||||
.map((e) => ProfileWidget.pubkey(e, size: 20)),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -53,16 +53,9 @@ class __ChatRaidMessage extends State<ChatRaidMessage>
|
||||
Widget build(BuildContext context) {
|
||||
if (_from == null || _to == null) return SizedBox.shrink();
|
||||
|
||||
final otherLink = (_isRaiding ? _to : _from).split(":");
|
||||
final otherEvent = ndk.requests.query(
|
||||
filters: [
|
||||
Filter(
|
||||
kinds: [int.parse(otherLink[0])],
|
||||
authors: [otherLink[1]],
|
||||
dTags: [otherLink[2]],
|
||||
),
|
||||
],
|
||||
);
|
||||
final otherTag = _isRaiding ? _to : _from;
|
||||
final otherLink = otherTag.split(":");
|
||||
final otherEvent = ndk.requests.query(filters: [aTagToFilter(otherTag)]);
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
|
@ -1,14 +1,11 @@
|
||||
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;
|
||||
|
Reference in New Issue
Block a user