mirror of
https://github.com/nostrlabs-io/zap-stream-flutter.git
synced 2025-06-16 20:08:50 +00:00
69
lib/widgets/button_follow.dart
Normal file
69
lib/widgets/button_follow.dart
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:zap_stream_flutter/main.dart';
|
||||||
|
import 'package:zap_stream_flutter/theme.dart';
|
||||||
|
import 'package:zap_stream_flutter/widgets/button.dart';
|
||||||
|
|
||||||
|
class FollowButton extends StatelessWidget {
|
||||||
|
final String pubkey;
|
||||||
|
final void Function()? onTap;
|
||||||
|
final void Function()? onFollow;
|
||||||
|
final void Function()? onUnfollow;
|
||||||
|
|
||||||
|
const FollowButton({
|
||||||
|
super.key,
|
||||||
|
required this.pubkey,
|
||||||
|
this.onTap,
|
||||||
|
this.onFollow,
|
||||||
|
this.onUnfollow,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final signer = ndk.accounts.getLoggedAccount()?.signer;
|
||||||
|
if (signer == null || signer.getPublicKey() == pubkey) {
|
||||||
|
return SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return FutureBuilder(
|
||||||
|
future: ndk.follows.getContactList(signer.getPublicKey()),
|
||||||
|
builder: (context, state) {
|
||||||
|
final follows = state.data?.contacts ?? [];
|
||||||
|
final isFollowing = follows.contains(pubkey);
|
||||||
|
return BasicButton(
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
spacing: 4,
|
||||||
|
children: [
|
||||||
|
Icon(isFollowing ? Icons.person_remove : Icons.person_add, size: 16),
|
||||||
|
Text(
|
||||||
|
isFollowing ? "Unfollow" : "Follow",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: DEFAULT_BR,
|
||||||
|
color: LAYER_2,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
if (onTap != null) {
|
||||||
|
onTap!();
|
||||||
|
}
|
||||||
|
if (isFollowing) {
|
||||||
|
await ndk.follows.broadcastRemoveContact(pubkey);
|
||||||
|
if (onUnfollow != null) {
|
||||||
|
onUnfollow!();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await ndk.follows.broadcastAddContact(pubkey);
|
||||||
|
if (onFollow != null) {
|
||||||
|
onFollow!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:ndk/ndk.dart';
|
import 'package:ndk/ndk.dart';
|
||||||
import 'package:zap_stream_flutter/theme.dart';
|
import 'package:zap_stream_flutter/theme.dart';
|
||||||
|
import 'package:zap_stream_flutter/widgets/button_follow.dart';
|
||||||
import 'package:zap_stream_flutter/widgets/mute_button.dart';
|
import 'package:zap_stream_flutter/widgets/mute_button.dart';
|
||||||
import 'package:zap_stream_flutter/widgets/nostr_text.dart';
|
import 'package:zap_stream_flutter/widgets/nostr_text.dart';
|
||||||
import 'package:zap_stream_flutter/widgets/profile.dart';
|
import 'package:zap_stream_flutter/widgets/profile.dart';
|
||||||
@ -75,6 +76,12 @@ class _ChatModalWidget extends State<ChatModalWidget> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (_showEmojiPicker) ReactionWidget(event: widget.event),
|
if (_showEmojiPicker) ReactionWidget(event: widget.event),
|
||||||
|
FollowButton(
|
||||||
|
pubkey: widget.event.pubKey,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
MuteButton(
|
MuteButton(
|
||||||
pubkey: widget.event.pubKey,
|
pubkey: widget.event.pubKey,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -39,7 +39,10 @@ class MuteButton extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||||
decoration: BoxDecoration(color: WARNING, borderRadius: DEFAULT_BR),
|
decoration: BoxDecoration(
|
||||||
|
color: isMuted ? LAYER_2 : WARNING,
|
||||||
|
borderRadius: DEFAULT_BR,
|
||||||
|
),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (onTap != null) {
|
if (onTap != null) {
|
||||||
onTap!();
|
onTap!();
|
||||||
|
@ -60,26 +60,34 @@ class StreamCardsWidget extends StatelessWidget {
|
|||||||
decoration: BoxDecoration(color: LAYER_2, borderRadius: DEFAULT_BR),
|
decoration: BoxDecoration(color: LAYER_2, borderRadius: DEFAULT_BR),
|
||||||
child: Column(
|
child: Column(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (title?.isNotEmpty ?? false)
|
if (title?.isNotEmpty ?? false)
|
||||||
Text(
|
Center(
|
||||||
title!,
|
child: Text(
|
||||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
title!,
|
||||||
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
if (image?.isNotEmpty ?? false)
|
if (image?.isNotEmpty ?? false)
|
||||||
link != null
|
Center(
|
||||||
? GestureDetector(
|
child:
|
||||||
onTap: () {
|
link != null
|
||||||
launchUrl(Uri.parse(link));
|
? GestureDetector(
|
||||||
},
|
onTap: () {
|
||||||
child: CachedNetworkImage(
|
launchUrl(Uri.parse(link));
|
||||||
imageUrl: proxyImg(context, image!),
|
},
|
||||||
errorWidget:
|
child: CachedNetworkImage(
|
||||||
(_, _, _) =>
|
imageUrl: proxyImg(context, image!),
|
||||||
SvgPicture.asset("assets/svg/logo.svg", height: 40),
|
errorWidget:
|
||||||
),
|
(_, _, _) => SvgPicture.asset(
|
||||||
)
|
"assets/svg/logo.svg",
|
||||||
: CachedNetworkImage(imageUrl: proxyImg(context, image!)),
|
height: 40,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: CachedNetworkImage(imageUrl: proxyImg(context, image!)),
|
||||||
|
),
|
||||||
MarkdownBody(
|
MarkdownBody(
|
||||||
data: card.content,
|
data: card.content,
|
||||||
onTapLink: (text, href, title) {
|
onTapLink: (text, href, title) {
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:zap_stream_flutter/theme.dart';
|
import 'package:zap_stream_flutter/theme.dart';
|
||||||
import 'package:zap_stream_flutter/utils.dart';
|
import 'package:zap_stream_flutter/utils.dart';
|
||||||
|
import 'package:zap_stream_flutter/widgets/button_follow.dart';
|
||||||
import 'package:zap_stream_flutter/widgets/profile.dart';
|
import 'package:zap_stream_flutter/widgets/profile.dart';
|
||||||
import 'package:zap_stream_flutter/widgets/stream_cards.dart';
|
import 'package:zap_stream_flutter/widgets/stream_cards.dart';
|
||||||
|
|
||||||
@ -23,6 +24,12 @@ class StreamInfoWidget extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ProfileWidget.pubkey(stream.info.host),
|
ProfileWidget.pubkey(stream.info.host),
|
||||||
|
FollowButton(
|
||||||
|
pubkey: stream.info.host,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
Text(
|
Text(
|
||||||
stream.info.title ?? "",
|
stream.info.title ?? "",
|
||||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
Reference in New Issue
Block a user