🎨 Optimize the null check in list
This commit is contained in:
@@ -120,83 +120,73 @@ class _PurchaseGiftSheetState extends State<PurchaseGiftSheet> {
|
|||||||
).colorScheme.outline.withOpacity(0.2),
|
).colorScheme.outline.withOpacity(0.2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child:
|
child: selectedRecipient != null
|
||||||
selectedRecipient != null
|
? ListTile(
|
||||||
? ListTile(
|
contentPadding: const EdgeInsets.only(
|
||||||
contentPadding: const EdgeInsets.only(
|
left: 20,
|
||||||
left: 20,
|
right: 12,
|
||||||
right: 12,
|
),
|
||||||
|
leading: ProfilePictureWidget(
|
||||||
|
file: selectedRecipient!.profile.picture,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
selectedRecipient!.nick,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
leading: ProfilePictureWidget(
|
),
|
||||||
file: selectedRecipient!.profile.picture,
|
subtitle: Text(
|
||||||
|
'selectedRecipient'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodySmall
|
||||||
|
?.copyWith(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: IconButton(
|
||||||
|
onPressed: () =>
|
||||||
|
setState(() => selectedRecipient = null),
|
||||||
|
icon: Icon(
|
||||||
|
Icons.clear,
|
||||||
|
color: Theme.of(context).colorScheme.error,
|
||||||
),
|
),
|
||||||
title: Text(
|
tooltip: 'Clear selection',
|
||||||
selectedRecipient!.nick,
|
),
|
||||||
style: const TextStyle(
|
)
|
||||||
fontSize: 16,
|
: Column(
|
||||||
fontWeight: FontWeight.w600,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
),
|
children: [
|
||||||
),
|
Icon(
|
||||||
subtitle: Text(
|
Icons.person_add_outlined,
|
||||||
'selectedRecipient'.tr(),
|
size: 48,
|
||||||
style: Theme.of(
|
color: Theme.of(
|
||||||
context,
|
context,
|
||||||
).textTheme.bodySmall?.copyWith(
|
).colorScheme.onSurfaceVariant,
|
||||||
color:
|
),
|
||||||
Theme.of(
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
'noRecipientSelected'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium
|
||||||
|
?.copyWith(
|
||||||
|
color: Theme.of(
|
||||||
context,
|
context,
|
||||||
).colorScheme.onSurfaceVariant,
|
).colorScheme.onSurfaceVariant,
|
||||||
),
|
|
||||||
),
|
|
||||||
trailing: IconButton(
|
|
||||||
onPressed:
|
|
||||||
() => setState(
|
|
||||||
() => selectedRecipient = null,
|
|
||||||
),
|
),
|
||||||
icon: Icon(
|
|
||||||
Icons.clear,
|
|
||||||
color: Theme.of(context).colorScheme.error,
|
|
||||||
),
|
|
||||||
tooltip: 'Clear selection',
|
|
||||||
),
|
),
|
||||||
)
|
const Gap(4),
|
||||||
: Column(
|
Text(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
'thisWillBeAnOpenGift'.tr(),
|
||||||
children: [
|
style: Theme.of(context).textTheme.bodySmall
|
||||||
Icon(
|
?.copyWith(
|
||||||
Icons.person_add_outlined,
|
color: Theme.of(
|
||||||
size: 48,
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
context,
|
||||||
).colorScheme.onSurfaceVariant,
|
).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
const Gap(8),
|
),
|
||||||
Text(
|
],
|
||||||
'noRecipientSelected'.tr(),
|
).padding(vertical: 32),
|
||||||
style: Theme.of(
|
|
||||||
context,
|
|
||||||
).textTheme.bodyMedium?.copyWith(
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(4),
|
|
||||||
Text(
|
|
||||||
'thisWillBeAnOpenGift'.tr(),
|
|
||||||
style: Theme.of(
|
|
||||||
context,
|
|
||||||
).textTheme.bodySmall?.copyWith(
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
).padding(vertical: 32),
|
|
||||||
),
|
),
|
||||||
const Gap(12),
|
const Gap(12),
|
||||||
OutlinedButton.icon(
|
OutlinedButton.icon(
|
||||||
@@ -259,8 +249,8 @@ class _PurchaseGiftSheetState extends State<PurchaseGiftSheet> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
onTapOutside:
|
onTapOutside: (_) =>
|
||||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -274,13 +264,12 @@ class _PurchaseGiftSheetState extends State<PurchaseGiftSheet> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: OutlinedButton(
|
child: OutlinedButton(
|
||||||
onPressed:
|
onPressed: () =>
|
||||||
() => Navigator.of(context).pop(<String, dynamic>{
|
Navigator.of(context).pop(<String, dynamic>{
|
||||||
'recipient': null,
|
'recipient': null,
|
||||||
'message':
|
'message': messageController.text.trim().isEmpty
|
||||||
messageController.text.trim().isEmpty
|
? null
|
||||||
? null
|
: messageController.text.trim(),
|
||||||
: messageController.text.trim(),
|
|
||||||
}),
|
}),
|
||||||
child: Text('skipRecipient'.tr()),
|
child: Text('skipRecipient'.tr()),
|
||||||
),
|
),
|
||||||
@@ -288,13 +277,12 @@ class _PurchaseGiftSheetState extends State<PurchaseGiftSheet> {
|
|||||||
const Gap(8),
|
const Gap(8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: FilledButton(
|
child: FilledButton(
|
||||||
onPressed:
|
onPressed: () =>
|
||||||
() => Navigator.of(context).pop(<String, dynamic>{
|
Navigator.of(context).pop(<String, dynamic>{
|
||||||
'recipient': selectedRecipient,
|
'recipient': selectedRecipient,
|
||||||
'message':
|
'message': messageController.text.trim().isEmpty
|
||||||
messageController.text.trim().isEmpty
|
? null
|
||||||
? null
|
: messageController.text.trim(),
|
||||||
: messageController.text.trim(),
|
|
||||||
}),
|
}),
|
||||||
child: Text('purchaseGift'.tr()),
|
child: Text('purchaseGift'.tr()),
|
||||||
),
|
),
|
||||||
@@ -336,40 +324,38 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
) {
|
) {
|
||||||
return stellarSubscriptionAsync.when(
|
return stellarSubscriptionAsync.when(
|
||||||
data: (membership) => _buildMembershipContent(context, ref, membership),
|
data: (membership) => _buildMembershipContent(context, ref, membership),
|
||||||
loading:
|
loading: () => Container(
|
||||||
() => Container(
|
width: double.infinity,
|
||||||
width: double.infinity,
|
padding: const EdgeInsets.all(16),
|
||||||
padding: const EdgeInsets.all(16),
|
decoration: BoxDecoration(
|
||||||
decoration: BoxDecoration(
|
gradient: LinearGradient(
|
||||||
gradient: LinearGradient(
|
colors: [
|
||||||
colors: [
|
Theme.of(context).colorScheme.primaryContainer,
|
||||||
Theme.of(context).colorScheme.primaryContainer,
|
Theme.of(context).colorScheme.secondaryContainer,
|
||||||
Theme.of(context).colorScheme.secondaryContainer,
|
],
|
||||||
],
|
begin: Alignment.topLeft,
|
||||||
begin: Alignment.topLeft,
|
end: Alignment.bottomRight,
|
||||||
end: Alignment.bottomRight,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
|
||||||
),
|
),
|
||||||
error:
|
borderRadius: BorderRadius.circular(12),
|
||||||
(error, stack) => Container(
|
),
|
||||||
width: double.infinity,
|
child: const Center(child: CircularProgressIndicator()),
|
||||||
padding: const EdgeInsets.all(16),
|
),
|
||||||
decoration: BoxDecoration(
|
error: (error, stack) => Container(
|
||||||
gradient: LinearGradient(
|
width: double.infinity,
|
||||||
colors: [
|
padding: const EdgeInsets.all(16),
|
||||||
Theme.of(context).colorScheme.primaryContainer,
|
decoration: BoxDecoration(
|
||||||
Theme.of(context).colorScheme.secondaryContainer,
|
gradient: LinearGradient(
|
||||||
],
|
colors: [
|
||||||
begin: Alignment.topLeft,
|
Theme.of(context).colorScheme.primaryContainer,
|
||||||
end: Alignment.bottomRight,
|
Theme.of(context).colorScheme.secondaryContainer,
|
||||||
),
|
],
|
||||||
borderRadius: BorderRadius.circular(12),
|
begin: Alignment.topLeft,
|
||||||
),
|
end: Alignment.bottomRight,
|
||||||
child: Text('Error loading membership: $error'),
|
|
||||||
),
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Text('Error loading membership: $error'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,118 +530,108 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children:
|
children: tiers.map((tier) {
|
||||||
tiers.map((tier) {
|
final isCurrentTier = currentMembership?.identifier == tier['id'];
|
||||||
final isCurrentTier = currentMembership?.identifier == tier['id'];
|
final tierColor = tier['color'] as Color;
|
||||||
final tierColor = tier['color'] as Color;
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
margin: const EdgeInsets.only(bottom: 8),
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap:
|
onTap: isCurrentTier
|
||||||
isCurrentTier
|
? null
|
||||||
? null
|
: () =>
|
||||||
: () => _purchaseMembership(
|
_purchaseMembership(context, ref, tier['id'] as String),
|
||||||
context,
|
borderRadius: BorderRadius.circular(8),
|
||||||
ref,
|
child: Container(
|
||||||
tier['id'] as String,
|
padding: const EdgeInsets.all(12),
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
|
color: isCurrentTier
|
||||||
|
? tierColor.withOpacity(0.1)
|
||||||
|
: Theme.of(context).colorScheme.surface,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
child: Container(
|
border: Border.all(
|
||||||
padding: const EdgeInsets.all(12),
|
color: isCurrentTier
|
||||||
decoration: BoxDecoration(
|
? tierColor
|
||||||
color:
|
: Theme.of(
|
||||||
isCurrentTier
|
context,
|
||||||
? tierColor.withOpacity(0.1)
|
).colorScheme.outline.withOpacity(0.2),
|
||||||
: Theme.of(context).colorScheme.surface,
|
width: isCurrentTier ? 2 : 1,
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(
|
|
||||||
color:
|
|
||||||
isCurrentTier
|
|
||||||
? tierColor
|
|
||||||
: Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.outline.withOpacity(0.2),
|
|
||||||
width: isCurrentTier ? 2 : 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 4,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: tierColor,
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
tier['name'] as String,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: isCurrentTier ? tierColor : null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(8),
|
|
||||||
if (isCurrentTier)
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 6,
|
|
||||||
vertical: 2,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: tierColor,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'membershipCurrentBadge'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 10,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
tier['price'] as String,
|
|
||||||
style: Theme.of(
|
|
||||||
context,
|
|
||||||
).textTheme.bodyMedium?.copyWith(
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!isCurrentTier)
|
|
||||||
Icon(
|
|
||||||
Icons.arrow_forward_ios,
|
|
||||||
size: 16,
|
|
||||||
color:
|
|
||||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 4,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: tierColor,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
tier['name'] as String,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: isCurrentTier ? tierColor : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
if (isCurrentTier)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 6,
|
||||||
|
vertical: 2,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: tierColor,
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'membershipCurrentBadge'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
tier['price'] as String,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium
|
||||||
|
?.copyWith(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (!isCurrentTier)
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios,
|
||||||
|
size: 16,
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}).toList(),
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -825,82 +801,75 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children:
|
children: tiers.map((tier) {
|
||||||
tiers.map((tier) {
|
final tierColor = tier['color'] as Color;
|
||||||
final tierColor = tier['color'] as Color;
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
margin: const EdgeInsets.only(bottom: 8),
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap:
|
onTap: () =>
|
||||||
() => _showPurchaseGiftDialog(
|
_showPurchaseGiftDialog(context, ref, tier['id'] as String),
|
||||||
context,
|
borderRadius: BorderRadius.circular(8),
|
||||||
ref,
|
child: Container(
|
||||||
tier['id'] as String,
|
padding: const EdgeInsets.all(12),
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
child: Container(
|
border: Border.all(
|
||||||
padding: const EdgeInsets.all(12),
|
color: Theme.of(
|
||||||
decoration: BoxDecoration(
|
context,
|
||||||
color: Theme.of(context).colorScheme.surface,
|
).colorScheme.outline.withOpacity(0.2),
|
||||||
borderRadius: BorderRadius.circular(8),
|
width: 1,
|
||||||
border: Border.all(
|
|
||||||
color: Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.outline.withOpacity(0.2),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 4,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: tierColor,
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
tier['name'] as String,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
tier['price'] as String,
|
|
||||||
style: Theme.of(
|
|
||||||
context,
|
|
||||||
).textTheme.bodyMedium?.copyWith(
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Icon(
|
|
||||||
Icons.arrow_forward_ios,
|
|
||||||
size: 16,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 4,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: tierColor,
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(12),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
tier['name'] as String,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
tier['price'] as String,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium
|
||||||
|
?.copyWith(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_ios,
|
||||||
|
size: 16,
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}).toList(),
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,8 +913,8 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(Icons.redeem),
|
icon: Icon(Icons.redeem),
|
||||||
onPressed:
|
onPressed: () =>
|
||||||
() => _redeemGift(context, ref, codeController.text.trim()),
|
_redeemGift(context, ref, codeController.text.trim()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
@@ -966,16 +935,16 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: OutlinedButton(
|
child: OutlinedButton(
|
||||||
onPressed:
|
onPressed: () =>
|
||||||
() => _showGiftHistorySheet(context, ref, sentGifts, true),
|
_showGiftHistorySheet(context, ref, sentGifts, true),
|
||||||
child: Text('sentGifts'.tr()),
|
child: Text('sentGifts'.tr()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: OutlinedButton(
|
child: OutlinedButton(
|
||||||
onPressed:
|
onPressed: () =>
|
||||||
() => _showGiftHistorySheet(context, ref, receivedGifts, false),
|
_showGiftHistorySheet(context, ref, receivedGifts, false),
|
||||||
child: Text('receivedGifts'.tr()),
|
child: Text('receivedGifts'.tr()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -993,36 +962,26 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
context: context,
|
context: context,
|
||||||
builder:
|
builder: (context) => SheetScaffold(
|
||||||
(context) => SheetScaffold(
|
titleText: isSent ? 'sentGifts'.tr() : 'receivedGifts'.tr(),
|
||||||
titleText: isSent ? 'sentGifts'.tr() : 'receivedGifts'.tr(),
|
child: giftsAsync.when(
|
||||||
child: giftsAsync.when(
|
data: (gifts) => gifts.isEmpty
|
||||||
data:
|
? Padding(
|
||||||
(gifts) =>
|
padding: const EdgeInsets.all(16),
|
||||||
gifts.isEmpty
|
child: Text(
|
||||||
? Padding(
|
isSent ? 'noSentGifts'.tr() : 'noReceivedGifts'.tr(),
|
||||||
padding: const EdgeInsets.all(16),
|
),
|
||||||
child: Text(
|
)
|
||||||
isSent
|
: ListView.builder(
|
||||||
? 'noSentGifts'.tr()
|
padding: const EdgeInsets.only(top: 16),
|
||||||
: 'noReceivedGifts'.tr(),
|
itemCount: gifts.length,
|
||||||
),
|
itemBuilder: (context, index) =>
|
||||||
)
|
_buildGiftItem(context, ref, gifts[index], isSent),
|
||||||
: ListView.builder(
|
),
|
||||||
padding: const EdgeInsets.only(top: 16),
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
itemCount: gifts.length,
|
error: (error, stack) => Center(child: Text('Error: $error')),
|
||||||
itemBuilder:
|
),
|
||||||
(context, index) => _buildGiftItem(
|
),
|
||||||
context,
|
|
||||||
ref,
|
|
||||||
gifts[index],
|
|
||||||
isSent,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
|
||||||
error: (error, stack) => Center(child: Text('Error: $error')),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1232,10 +1191,10 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
'/pass/subscriptions/gifts/purchase',
|
'/pass/subscriptions/gifts/purchase',
|
||||||
data: {
|
data: {
|
||||||
'subscription_identifier': subscriptionId,
|
'subscription_identifier': subscriptionId,
|
||||||
if (recipientId != null) 'recipient_id': recipientId,
|
'recipient_id': ?recipientId,
|
||||||
'payment_method': 'solian.wallet',
|
'payment_method': 'solian.wallet',
|
||||||
'payment_details': {'currency': 'golds'},
|
'payment_details': {'currency': 'golds'},
|
||||||
if (message != null) 'message': message,
|
'message': ?message,
|
||||||
'gift_duration_days': 30,
|
'gift_duration_days': 30,
|
||||||
'subscription_duration_days': 30,
|
'subscription_duration_days': 30,
|
||||||
},
|
},
|
||||||
@@ -1277,83 +1236,75 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
await showModalBottomSheet(
|
await showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder:
|
builder: (context) => SheetScaffold(
|
||||||
(context) => SheetScaffold(
|
titleText: 'giftPurchased'.tr(),
|
||||||
titleText: 'giftPurchased'.tr(),
|
child: Padding(
|
||||||
child: Padding(
|
padding: const EdgeInsets.all(16),
|
||||||
padding: const EdgeInsets.all(16),
|
child: Column(
|
||||||
child: Column(
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisSize: MainAxisSize.min,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
children: [
|
||||||
children: [
|
Container(
|
||||||
Container(
|
padding: const EdgeInsets.all(12),
|
||||||
padding: const EdgeInsets.all(12),
|
decoration: BoxDecoration(
|
||||||
decoration: BoxDecoration(
|
color: Theme.of(context).colorScheme.surface,
|
||||||
color: Theme.of(context).colorScheme.surface,
|
borderRadius: BorderRadius.circular(8),
|
||||||
borderRadius: BorderRadius.circular(8),
|
border: Border.all(
|
||||||
border: Border.all(
|
color: Theme.of(
|
||||||
color: Theme.of(
|
context,
|
||||||
context,
|
).colorScheme.outline.withOpacity(0.2),
|
||||||
).colorScheme.outline.withOpacity(0.2),
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
updatedGift.giftCode,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Row(
|
IconButton(
|
||||||
children: [
|
onPressed: () async {
|
||||||
Expanded(
|
await Clipboard.setData(
|
||||||
child: Text(
|
ClipboardData(text: updatedGift.giftCode),
|
||||||
updatedGift.giftCode,
|
);
|
||||||
style: TextStyle(
|
if (context.mounted) {
|
||||||
fontSize: 16,
|
showSnackBar('giftCodeCopiedToClipboard'.tr());
|
||||||
fontWeight: FontWeight.w600,
|
}
|
||||||
fontFamily: 'monospace',
|
},
|
||||||
),
|
icon: const Icon(Icons.copy),
|
||||||
),
|
tooltip: 'copyGiftCode'.tr(),
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () async {
|
|
||||||
await Clipboard.setData(
|
|
||||||
ClipboardData(text: updatedGift.giftCode),
|
|
||||||
);
|
|
||||||
if (context.mounted) {
|
|
||||||
showSnackBar(
|
|
||||||
'giftCodeCopiedToClipboard'.tr(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.copy),
|
|
||||||
tooltip: 'copyGiftCode'.tr(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(16),
|
|
||||||
Text(
|
|
||||||
'shareCodeWithRecipient'.tr(),
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
|
||||||
),
|
|
||||||
if (updatedGift.recipientId == null) ...[
|
|
||||||
const Gap(8),
|
|
||||||
Text(
|
|
||||||
'openGiftAnyoneCanRedeem'.tr(),
|
|
||||||
style: Theme.of(
|
|
||||||
context,
|
|
||||||
).textTheme.bodySmall?.copyWith(
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const Gap(24),
|
),
|
||||||
FilledButton(
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
child: Text('ok'.tr()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
const Gap(16),
|
||||||
|
Text(
|
||||||
|
'shareCodeWithRecipient'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
if (updatedGift.recipientId == null) ...[
|
||||||
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
'openGiftAnyoneCanRedeem'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
const Gap(24),
|
||||||
|
FilledButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text('ok'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1397,17 +1348,16 @@ class StellarProgramTab extends HookConsumerWidget {
|
|||||||
hideLoadingModal(context);
|
hideLoadingModal(context);
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder:
|
builder: (context) => AlertDialog(
|
||||||
(context) => AlertDialog(
|
title: Text('giftRedeemed'.tr()),
|
||||||
title: Text('giftRedeemed'.tr()),
|
content: Text('giftRedeemedSuccessfully'.tr()),
|
||||||
content: Text('giftRedeemedSuccessfully'.tr()),
|
actions: [
|
||||||
actions: [
|
FilledButton(
|
||||||
FilledButton(
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
child: Text('ok'.tr()),
|
||||||
child: Text('ok'.tr()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -398,10 +398,7 @@ class CallOverlayBar extends HookConsumerWidget {
|
|||||||
layoutBuilder: (currentChild, previousChildren) {
|
layoutBuilder: (currentChild, previousChildren) {
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.topCenter,
|
alignment: Alignment.topCenter,
|
||||||
children: <Widget>[
|
children: <Widget>[...previousChildren, ?currentChild],
|
||||||
...previousChildren,
|
|
||||||
if (currentChild != null) currentChild,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: child,
|
child: child,
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class ChatRoomSubtitle extends StatelessWidget {
|
|||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
layoutBuilder: (currentChild, previousChildren) => Stack(
|
layoutBuilder: (currentChild, previousChildren) => Stack(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
children: [...previousChildren, if (currentChild != null) currentChild],
|
children: [...previousChildren, ?currentChild],
|
||||||
),
|
),
|
||||||
child: summary.when(
|
child: summary.when(
|
||||||
data: (data) => Container(
|
data: (data) => Container(
|
||||||
|
|||||||
@@ -478,10 +478,7 @@ class PostItem extends HookConsumerWidget {
|
|||||||
|
|
||||||
final translationSection = Column(
|
final translationSection = Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [?translatedWidget, ?translatableWidget],
|
||||||
if (translatedWidget != null) translatedWidget,
|
|
||||||
if (translatableWidget != null) translatableWidget,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
|||||||
@@ -854,7 +854,7 @@ class PostHeader extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (trailing != null) trailing!,
|
?trailing,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1142,7 +1142,7 @@ class PostBody extends ConsumerWidget {
|
|||||||
attachments: item.attachments,
|
attachments: item.attachments,
|
||||||
noMentionChip: item.fediverseUri != null,
|
noMentionChip: item.fediverseUri != null,
|
||||||
),
|
),
|
||||||
if (translationSection != null) translationSection!,
|
?translationSection,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user