mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 12:38:24 +00:00
UsersRichText improvements, signedInUserProvider
This commit is contained in:
@@ -247,6 +247,14 @@ mixin UserAdapter on NostrAdapter<User> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final signedInUserProvider = Provider<User?>((ref) {
|
||||||
|
return ref.settings
|
||||||
|
.watchOne('_', alsoWatch: (_) => {_.user})
|
||||||
|
.model
|
||||||
|
?.user
|
||||||
|
.value;
|
||||||
|
});
|
||||||
|
|
||||||
const kZapstorePubkey =
|
const kZapstorePubkey =
|
||||||
'78ce6faa72264387284e647ba6938995735ec8c7d5c5a65737e55130f026307d';
|
'78ce6faa72264387284e647ba6938995735ec8c7d5c5a65737e55130f026307d';
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,7 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
final systemInfoState = ref.watch(systemInfoNotifierProvider);
|
final systemInfoState = ref.watch(systemInfoNotifierProvider);
|
||||||
|
|
||||||
final feedbackController = useTextEditingController();
|
final feedbackController = useTextEditingController();
|
||||||
final user = ref.settings
|
final signedInUser = ref.watch(signedInUserProvider);
|
||||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
|
||||||
.model!
|
|
||||||
.user
|
|
||||||
.value;
|
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -57,16 +53,17 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
maxLines: 10,
|
maxLines: 10,
|
||||||
),
|
),
|
||||||
Gap(20),
|
Gap(20),
|
||||||
if (user == null) SignInButton(minimal: true),
|
if (signedInUser == null) SignInButton(minimal: true),
|
||||||
if (user != null &&
|
if (signedInUser != null &&
|
||||||
user.settings.value!.signInMethod != SignInMethod.nip55 ||
|
signedInUser.settings.value!.signInMethod !=
|
||||||
|
SignInMethod.nip55 ||
|
||||||
!amberSigner.isAvailable)
|
!amberSigner.isAvailable)
|
||||||
Text(
|
Text(
|
||||||
'To share feedback, you must be signed in with Amber. You can also message us on nostr!',
|
'To share feedback, you must be signed in with Amber. You can also message us on nostr!',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.red[300], fontWeight: FontWeight.bold)),
|
color: Colors.red[300], fontWeight: FontWeight.bold)),
|
||||||
if (user != null &&
|
if (signedInUser != null &&
|
||||||
user.settings.value!.signInMethod == SignInMethod.nip55 &&
|
signedInUser.settings.value!.signInMethod == SignInMethod.nip55 &&
|
||||||
amberSigner.isAvailable)
|
amberSigner.isAvailable)
|
||||||
AsyncButtonBuilder(
|
AsyncButtonBuilder(
|
||||||
loadingWidget: SmallCircularProgressIndicator(),
|
loadingWidget: SmallCircularProgressIndicator(),
|
||||||
@@ -76,7 +73,7 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
PartialDirectMessage(
|
PartialDirectMessage(
|
||||||
content: feedbackController.text.trim(),
|
content: feedbackController.text.trim(),
|
||||||
receiver: kZapstorePubkey.npub),
|
receiver: kZapstorePubkey.npub),
|
||||||
withPubkey: user.pubkey);
|
withPubkey: signedInUser.pubkey);
|
||||||
try {
|
try {
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
Uri.parse('https://relay.zapstore.dev/'),
|
Uri.parse('https://relay.zapstore.dev/'),
|
||||||
@@ -98,15 +95,9 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
builder: (context, child, callback, state) {
|
builder: (context, child, callback, state) =>
|
||||||
return switch (state) {
|
ElevatedButton(onPressed: callback, child: child),
|
||||||
_ => ElevatedButton(
|
child: Text('Send as ${signedInUser.nameOrNpub}'),
|
||||||
onPressed: callback,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
child: Text('Send as ${user.nameOrNpub}'),
|
|
||||||
),
|
),
|
||||||
Gap(20),
|
Gap(20),
|
||||||
Divider(),
|
Divider(),
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:purplebase/purplebase.dart' as base;
|
import 'package:purplebase/purplebase.dart' as base;
|
||||||
import 'package:zapstore/main.data.dart';
|
|
||||||
import 'package:zapstore/models/app.dart';
|
import 'package:zapstore/models/app.dart';
|
||||||
import 'package:zapstore/models/settings.dart';
|
|
||||||
import 'package:zapstore/models/user.dart';
|
import 'package:zapstore/models/user.dart';
|
||||||
import 'package:zapstore/widgets/sign_in_container.dart';
|
import 'package:zapstore/widgets/sign_in_container.dart';
|
||||||
import 'package:zapstore/widgets/author_container.dart';
|
import 'package:zapstore/widgets/author_container.dart';
|
||||||
@@ -22,11 +20,7 @@ class InstallAlertDialog extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final trustedSignerNotifier = useState(false);
|
final trustedSignerNotifier = useState(false);
|
||||||
final user = ref.settings
|
final signedInUser = ref.watch(signedInUserProvider);
|
||||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
|
||||||
.model!
|
|
||||||
.user
|
|
||||||
.value;
|
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
elevation: 10,
|
elevation: 10,
|
||||||
@@ -50,10 +44,10 @@ class InstallAlertDialog extends HookConsumerWidget {
|
|||||||
Gap(20),
|
Gap(20),
|
||||||
if (app.signer.value != null)
|
if (app.signer.value != null)
|
||||||
WebOfTrustContainer(
|
WebOfTrustContainer(
|
||||||
fromNpub: user?.npub ?? kFranzapPubkey.npub,
|
fromNpub: signedInUser?.npub ?? kFranzapPubkey.npub,
|
||||||
toNpub: app.signer.value!.npub,
|
toNpub: app.signer.value!.npub,
|
||||||
),
|
),
|
||||||
if (user == null)
|
if (signedInUser == null)
|
||||||
SignInButton(
|
SignInButton(
|
||||||
label: 'Sign in to view your web of trust',
|
label: 'Sign in to view your web of trust',
|
||||||
minimal: true,
|
minimal: true,
|
||||||
|
|||||||
@@ -26,11 +26,7 @@ class SignInButton extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final user = ref.settings
|
final user = ref.watch(signedInUserProvider);
|
||||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
|
||||||
.model
|
|
||||||
?.user
|
|
||||||
.value;
|
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:zapstore/main.data.dart';
|
import 'package:zapstore/models/user.dart';
|
||||||
import 'package:zapstore/models/settings.dart';
|
|
||||||
import 'package:zapstore/widgets/rounded_image.dart';
|
import 'package:zapstore/widgets/rounded_image.dart';
|
||||||
|
|
||||||
class UserAvatar extends HookConsumerWidget {
|
class UserAvatar extends HookConsumerWidget {
|
||||||
@@ -9,11 +8,7 @@ class UserAvatar extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final user = ref.settings
|
final signedInUser = ref.watch(signedInUserProvider);
|
||||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
return RoundedImage(url: signedInUser?.avatarUrl, size: 46);
|
||||||
.model!
|
|
||||||
.user
|
|
||||||
.value;
|
|
||||||
return RoundedImage(url: user?.avatarUrl, size: 46);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,55 +3,75 @@ import 'package:zapstore/models/user.dart';
|
|||||||
import 'package:zapstore/widgets/rounded_image.dart';
|
import 'package:zapstore/widgets/rounded_image.dart';
|
||||||
|
|
||||||
class UsersRichText extends StatelessWidget {
|
class UsersRichText extends StatelessWidget {
|
||||||
const UsersRichText({
|
final TextSpan? leadingTextSpan;
|
||||||
super.key,
|
|
||||||
this.leadingText,
|
|
||||||
this.trailingText,
|
|
||||||
required this.users,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String? leadingText;
|
|
||||||
final String? trailingText;
|
final String? trailingText;
|
||||||
final List<User> users;
|
final List<User> users;
|
||||||
|
final User? signedInUser;
|
||||||
|
final int? maxUsersToDisplay;
|
||||||
|
final double fontSize;
|
||||||
|
|
||||||
|
const UsersRichText({
|
||||||
|
super.key,
|
||||||
|
this.leadingTextSpan,
|
||||||
|
this.trailingText,
|
||||||
|
required this.users,
|
||||||
|
this.signedInUser,
|
||||||
|
this.maxUsersToDisplay,
|
||||||
|
this.fontSize = 16,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
// Move signed in user to head of list
|
||||||
|
if (users.remove(signedInUser)) {
|
||||||
|
users.insert(0, signedInUser!);
|
||||||
|
}
|
||||||
|
final usersToDisplay = maxUsersToDisplay != null
|
||||||
|
? users.take(maxUsersToDisplay!).toList()
|
||||||
|
: users;
|
||||||
|
|
||||||
return RichText(
|
return RichText(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
children: [
|
children: [
|
||||||
if (leadingText != null)
|
for (final user in usersToDisplay)
|
||||||
TextSpan(text: leadingText!, style: TextStyle(fontSize: 15)),
|
|
||||||
for (final user in users)
|
|
||||||
TextSpan(
|
|
||||||
children: [
|
|
||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
alignment: PlaceholderAlignment.middle,
|
alignment: PlaceholderAlignment.middle,
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 1,
|
spacing: 0,
|
||||||
runSpacing: 10,
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
RoundedImage(url: user.avatarUrl, size: 20),
|
if (usersToDisplay.indexOf(user) == 0 &&
|
||||||
|
leadingTextSpan != null)
|
||||||
|
RichText(text: leadingTextSpan!),
|
||||||
|
if (user != signedInUser)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 2, right: 2),
|
||||||
|
child: RoundedImage(url: user.avatarUrl, size: 20),
|
||||||
|
),
|
||||||
Text(
|
Text(
|
||||||
' ${user.nameOrNpub}',
|
user == signedInUser
|
||||||
|
? (leadingTextSpan != null ? ' you' : 'You')
|
||||||
|
: ' ${user.nameOrNpub}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15, fontWeight: FontWeight.bold),
|
fontSize: fontSize, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
users.indexOf(user) == users.length - 1
|
usersToDisplay.indexOf(user) == usersToDisplay.length - 1
|
||||||
? ''
|
? ''
|
||||||
: (users.indexOf(user) == users.length - 2
|
: (usersToDisplay.indexOf(user) ==
|
||||||
? ' and '
|
usersToDisplay.length - 2
|
||||||
|
? usersToDisplay.length < users.length
|
||||||
|
? ', '
|
||||||
|
: ' and '
|
||||||
: ', '),
|
: ', '),
|
||||||
style: TextStyle(fontSize: 15),
|
style: TextStyle(fontSize: fontSize)),
|
||||||
),
|
if (usersToDisplay.indexOf(user) == usersToDisplay.length - 1)
|
||||||
|
Text(
|
||||||
|
'${usersToDisplay.length < users.length ? ' and ${users.length - usersToDisplay.length} others' : ''}${trailingText ?? ''}',
|
||||||
|
style: TextStyle(fontSize: fontSize))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (users.indexOf(user) == users.length - 1)
|
|
||||||
TextSpan(text: trailingText, style: TextStyle(fontSize: 15))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:purplebase/purplebase.dart' as base;
|
|
||||||
import 'package:zapstore/main.data.dart';
|
import 'package:zapstore/main.data.dart';
|
||||||
import 'package:zapstore/models/settings.dart';
|
|
||||||
import 'package:zapstore/models/user.dart';
|
import 'package:zapstore/models/user.dart';
|
||||||
import 'package:zapstore/screens/settings_screen.dart';
|
import 'package:zapstore/screens/settings_screen.dart';
|
||||||
import 'package:zapstore/widgets/users_rich_text.dart';
|
import 'package:zapstore/widgets/users_rich_text.dart';
|
||||||
@@ -23,25 +20,20 @@ class WebOfTrustContainer extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final data =
|
final data =
|
||||||
ref.watch(followsWhoFollowProvider((from: fromNpub, to: toNpub)));
|
ref.watch(followsWhoFollowProvider((from: fromNpub, to: toNpub)));
|
||||||
|
final signedInUser = ref.watch(signedInUserProvider);
|
||||||
|
|
||||||
return switch (data) {
|
return switch (data) {
|
||||||
AsyncData<List<User>>(value: final trustedUsers) => Builder(
|
AsyncData<List<User>>(value: final trustedUsers) => Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
final hasUser =
|
if (trustedUsers.isEmpty) {
|
||||||
trustedUsers.firstWhereOrNull((u) => u.npub == fromNpub) !=
|
|
||||||
null;
|
|
||||||
final trustedUsersWithoutLoggedInUser =
|
|
||||||
trustedUsers.where((u) => u.npub != fromNpub).toList();
|
|
||||||
if (trustedUsersWithoutLoggedInUser.isEmpty) {
|
|
||||||
return Text(
|
return Text(
|
||||||
'No trusted users between you and the signer. (This may be a service error)');
|
'No trusted users between you and the signer. (This may be a service error)');
|
||||||
}
|
}
|
||||||
|
|
||||||
return UsersRichText(
|
return UsersRichText(
|
||||||
leadingText:
|
users: trustedUsers,
|
||||||
hasUser && fromNpub != kFranzapPubkey.npub ? 'You, ' : null,
|
signedInUser: signedInUser,
|
||||||
trailingText: ' and others follow this signer on nostr.',
|
trailingText: ' and others follow this signer on nostr.',
|
||||||
users: trustedUsersWithoutLoggedInUser,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -66,8 +58,7 @@ class WebOfTrustContainer extends HookConsumerWidget {
|
|||||||
|
|
||||||
final followsWhoFollowProvider = FutureProvider.autoDispose
|
final followsWhoFollowProvider = FutureProvider.autoDispose
|
||||||
.family<List<User>, ({String from, String to})>((ref, arg) async {
|
.family<List<User>, ({String from, String to})>((ref, arg) async {
|
||||||
final _ =
|
final _ = ref.watch(signedInUserProvider);
|
||||||
ref.settings.watchOne('_', alsoWatch: (_) => {_.user}).model!.user.value;
|
|
||||||
final users = await ref.users.userAdapter.getTrusted(arg.from, arg.to);
|
final users = await ref.users.userAdapter.getTrusted(arg.from, arg.to);
|
||||||
return users.toSet().toList();
|
return users.toSet().toList();
|
||||||
});
|
});
|
||||||
|
|||||||
+18
-15
@@ -1,9 +1,10 @@
|
|||||||
|
import 'package:async_button_builder/async_button_builder.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:zapstore/main.data.dart';
|
import 'package:zapstore/main.data.dart';
|
||||||
import 'package:zapstore/models/app.dart';
|
import 'package:zapstore/models/app.dart';
|
||||||
import 'package:zapstore/models/settings.dart';
|
import 'package:zapstore/models/user.dart';
|
||||||
import 'package:zapstore/navigation/app_initializer.dart';
|
import 'package:zapstore/navigation/app_initializer.dart';
|
||||||
import 'package:zapstore/screens/settings_screen.dart';
|
import 'package:zapstore/screens/settings_screen.dart';
|
||||||
import 'package:zapstore/utils/extensions.dart';
|
import 'package:zapstore/utils/extensions.dart';
|
||||||
@@ -30,7 +31,16 @@ class ZapButton extends HookConsumerWidget {
|
|||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ElevatedButton(
|
return AsyncButtonBuilder(
|
||||||
|
loadingWidget: Text('⚡️ Zapping...').bold,
|
||||||
|
builder: (context, child, callback, state) => ElevatedButton(
|
||||||
|
onPressed: callback,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color.fromARGB(255, 60, 60, 54),
|
||||||
|
disabledBackgroundColor: Colors.grey[600],
|
||||||
|
),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
onPressed: nwcConnection.isLoading
|
onPressed: nwcConnection.isLoading
|
||||||
? null
|
? null
|
||||||
: () async {
|
: () async {
|
||||||
@@ -59,13 +69,10 @@ class ZapButton extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Consumer(
|
Consumer(
|
||||||
builder: (context, ref, _) {
|
builder: (context, ref, _) {
|
||||||
final user = ref.settings
|
final signedInUser =
|
||||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
ref.watch(signedInUserProvider);
|
||||||
.model!
|
|
||||||
.user
|
|
||||||
.value;
|
|
||||||
|
|
||||||
if (user == null) {
|
if (signedInUser == null) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
@@ -141,10 +148,10 @@ class ZapButton extends HookConsumerWidget {
|
|||||||
if (amount > 0) {
|
if (amount > 0) {
|
||||||
try {
|
try {
|
||||||
// Reload user as we are in a callback and it could have changed
|
// Reload user as we are in a callback and it could have changed
|
||||||
final loggedInUser =
|
final signedInUser =
|
||||||
ref.settings.findOneLocalById('_')!.user.value;
|
ref.settings.findOneLocalById('_')!.user.value;
|
||||||
if (loggedInUser != null) {
|
if (signedInUser != null) {
|
||||||
await loggedInUser.zap(amount,
|
await signedInUser.zap(amount,
|
||||||
event: app.latestMetadata!, comment: comment);
|
event: app.latestMetadata!, comment: comment);
|
||||||
} else {
|
} else {
|
||||||
await anonUser!.zap(amount,
|
await anonUser!.zap(amount,
|
||||||
@@ -161,10 +168,6 @@ class ZapButton extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: Colors.grey[800],
|
|
||||||
disabledBackgroundColor: Colors.grey[500],
|
|
||||||
),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'⚡️ Zap this release',
|
'⚡️ Zap this release',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ class ZapReceipts extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final signedInUser = ref.watch(signedInUserProvider);
|
||||||
|
|
||||||
// NOTE: These watchers will become more efficient
|
// NOTE: These watchers will become more efficient
|
||||||
ref.users.watchAll();
|
ref.users.watchAll();
|
||||||
|
|
||||||
@@ -47,14 +49,25 @@ class ZapReceipts extends HookConsumerWidget {
|
|||||||
final receipts = zapReceipts.value!;
|
final receipts = zapReceipts.value!;
|
||||||
final totalAmountInSats = receipts.fold(0, (acc, e) => acc + e.amount);
|
final totalAmountInSats = receipts.fold(0, (acc, e) => acc + e.amount);
|
||||||
|
|
||||||
final senderIds = receipts.map((r) => r.senderPubkey).toSet();
|
final zapperIds = receipts.map((r) => r.senderPubkey).toSet();
|
||||||
final senders = ref.users.findManyLocalByIds(senderIds);
|
final zappers = ref.users.findManyLocalByIds(zapperIds);
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(top: 10, bottom: 10),
|
padding: const EdgeInsets.only(top: 10, bottom: 10),
|
||||||
child: UsersRichText(
|
child: UsersRichText(
|
||||||
leadingText: '⚡ $totalAmountInSats sats zapped from ',
|
leadingTextSpan: TextSpan(
|
||||||
users: senders,
|
style: TextStyle(fontSize: 16),
|
||||||
|
children: [
|
||||||
|
TextSpan(text: '⚡'),
|
||||||
|
TextSpan(
|
||||||
|
text: ' $totalAmountInSats sats ',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
TextSpan(text: 'zapped by'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
users: zappers,
|
||||||
|
signedInUser: signedInUser,
|
||||||
|
maxUsersToDisplay: 5,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user