⚡ Prefer auto dispose riverpods
This commit is contained in:
@@ -14,7 +14,7 @@ Future<Map<String, dynamic>?> billingUsage(Ref ref) async {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
final indexedCloudFileListProvider = AsyncNotifierProvider(
|
||||
final indexedCloudFileListProvider = AsyncNotifierProvider.autoDispose(
|
||||
IndexedCloudFileListNotifier.new,
|
||||
);
|
||||
|
||||
@@ -76,10 +76,10 @@ class IndexedCloudFileListNotifier extends AsyncNotifier<List<FileListItem>>
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
|
||||
final List<String> folders =
|
||||
(response.data['folders'] as List).map((e) => e as String).toList();
|
||||
final List<SnCloudFileIndex> files =
|
||||
(response.data['files'] as List)
|
||||
final List<String> folders = (response.data['folders'] as List)
|
||||
.map((e) => e as String)
|
||||
.toList();
|
||||
final List<SnCloudFileIndex> files = (response.data['files'] as List)
|
||||
.map((e) => SnCloudFileIndex.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
|
||||
@@ -92,7 +92,7 @@ class IndexedCloudFileListNotifier extends AsyncNotifier<List<FileListItem>>
|
||||
}
|
||||
}
|
||||
|
||||
final unindexedFileListProvider = AsyncNotifierProvider(
|
||||
final unindexedFileListProvider = AsyncNotifierProvider.autoDispose(
|
||||
UnindexedFileListNotifier.new,
|
||||
);
|
||||
|
||||
@@ -165,13 +165,13 @@ class UnindexedFileListNotifier extends AsyncNotifier<List<FileListItem>>
|
||||
|
||||
totalCount = int.tryParse(response.headers.value('x-total') ?? '0') ?? 0;
|
||||
|
||||
final List<SnCloudFile> files =
|
||||
(response.data as List)
|
||||
final List<SnCloudFile> files = (response.data as List)
|
||||
.map((e) => SnCloudFile.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
|
||||
final List<FileListItem> items =
|
||||
files.map((file) => FileListItem.unindexedFile(file)).toList();
|
||||
final List<FileListItem> items = files
|
||||
.map((file) => FileListItem.unindexedFile(file))
|
||||
.toList();
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Future<double> socialCredits(Ref ref) async {
|
||||
return response.data?.toDouble() ?? 0.0;
|
||||
}
|
||||
|
||||
final socialCreditHistoryNotifierProvider = AsyncNotifierProvider(
|
||||
final socialCreditHistoryNotifierProvider = AsyncNotifierProvider.autoDispose(
|
||||
SocialCreditHistoryNotifier.new,
|
||||
);
|
||||
|
||||
@@ -45,8 +45,7 @@ class SocialCreditHistoryNotifier
|
||||
|
||||
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||
|
||||
final records =
|
||||
response.data
|
||||
final records = response.data
|
||||
.map((json) => SnSocialCreditRecord.fromJson(json))
|
||||
.cast<SnSocialCreditRecord>()
|
||||
.toList();
|
||||
@@ -68,8 +67,7 @@ class SocialCreditsTab extends HookConsumerWidget {
|
||||
margin: const EdgeInsets.only(left: 16, right: 16, top: 8),
|
||||
child: socialCredits
|
||||
.when(
|
||||
data:
|
||||
(credits) => Stack(
|
||||
data: (credits) => Stack(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -83,9 +81,7 @@ class SocialCreditsTab extends HookConsumerWidget {
|
||||
? 'socialCreditsLevelGood'.tr()
|
||||
: 'socialCreditsLevelExcellent'.tr(),
|
||||
).tr().bold().fontSize(20),
|
||||
Text(
|
||||
'${credits.toStringAsFixed(2)} pts',
|
||||
).fontSize(14),
|
||||
Text('${credits.toStringAsFixed(2)} pts').fontSize(14),
|
||||
const Gap(8),
|
||||
LinearProgressIndicator(value: credits / 200),
|
||||
],
|
||||
@@ -119,8 +115,7 @@ class SocialCreditsTab extends HookConsumerWidget {
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
title: Text(
|
||||
record.reason,
|
||||
style:
|
||||
isExpired
|
||||
style: isExpired
|
||||
? TextStyle(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: Theme.of(
|
||||
|
||||
@@ -14,7 +14,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:island/widgets/paging/pagination_list.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
final levelingHistoryNotifierProvider = AsyncNotifierProvider(
|
||||
final levelingHistoryNotifierProvider = AsyncNotifierProvider.autoDispose(
|
||||
LevelingHistoryNotifier.new,
|
||||
);
|
||||
|
||||
@@ -35,8 +35,7 @@ class LevelingHistoryNotifier extends AsyncNotifier<List<SnExperienceRecord>>
|
||||
|
||||
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||
|
||||
final List<SnExperienceRecord> records =
|
||||
response.data
|
||||
final List<SnExperienceRecord> records = response.data
|
||||
.map((json) => SnExperienceRecord.fromJson(json))
|
||||
.cast<SnExperienceRecord>()
|
||||
.toList();
|
||||
@@ -162,8 +161,9 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
stopIndicatorRadius: 0,
|
||||
trackGap: 0,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
backgroundColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
),
|
||||
],
|
||||
@@ -186,8 +186,7 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
notifier: levelingHistoryNotifierProvider.notifier,
|
||||
isRefreshable: false,
|
||||
isSliver: true,
|
||||
itemBuilder:
|
||||
(context, idx, record) => ListTile(
|
||||
itemBuilder: (context, idx, record) => ListTile(
|
||||
title: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
@@ -208,9 +207,7 @@ class LevelingScreen extends HookConsumerWidget {
|
||||
subtitle: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
'${record.delta > 0 ? '+' : ''}${record.delta} EXP',
|
||||
),
|
||||
Text('${record.delta > 0 ? '+' : ''}${record.delta} EXP'),
|
||||
if (record.bonusMultiplier != 1.0)
|
||||
Text('x${record.bonusMultiplier}'),
|
||||
],
|
||||
@@ -249,8 +246,7 @@ class LevelStairsPainter extends CustomPainter {
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final paint =
|
||||
Paint()
|
||||
final paint = Paint()
|
||||
..color = surfaceColor.withOpacity(0.2)
|
||||
..strokeWidth = 1.5
|
||||
..style = PaintingStyle.stroke;
|
||||
|
||||
@@ -29,7 +29,7 @@ Future<List<SnRelationship>> sentFriendRequest(Ref ref) async {
|
||||
.toList();
|
||||
}
|
||||
|
||||
final relationshipListNotifierProvider = AsyncNotifierProvider(
|
||||
final relationshipListNotifierProvider = AsyncNotifierProvider.autoDispose(
|
||||
RelationshipListNotifier.new,
|
||||
);
|
||||
|
||||
@@ -45,8 +45,7 @@ class RelationshipListNotifier extends AsyncNotifier<List<SnRelationship>>
|
||||
queryParameters: {'offset': fetchedCount.toString(), 'take': take},
|
||||
);
|
||||
|
||||
final List<SnRelationship> items =
|
||||
(response.data as List)
|
||||
final List<SnRelationship> items = (response.data as List)
|
||||
.map((e) => SnRelationship.fromJson(e as Map<String, dynamic>))
|
||||
.cast<SnRelationship>()
|
||||
.toList();
|
||||
@@ -83,8 +82,9 @@ class RelationshipListTile extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final account =
|
||||
showRelatedAccount ? relationship.related : relationship.account;
|
||||
final account = showRelatedAccount
|
||||
? relationship.related
|
||||
: relationship.account;
|
||||
final isPending =
|
||||
relationship.status == 0 && relationship.relatedId == currentUserId;
|
||||
final isWaiting =
|
||||
@@ -138,8 +138,7 @@ class RelationshipListTile extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
subtitle: Text('@${account.name}'),
|
||||
trailing:
|
||||
showActions
|
||||
trailing: showActions
|
||||
? Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@@ -165,8 +164,7 @@ class RelationshipListTile extends StatelessWidget {
|
||||
PopupMenuButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: const Icon(Symbols.more_vert),
|
||||
itemBuilder:
|
||||
(context) => [
|
||||
itemBuilder: (context) => [
|
||||
if (relationship.status >= 100) // If friend
|
||||
PopupMenuItem(
|
||||
child: ListTile(
|
||||
@@ -174,11 +172,7 @@ class RelationshipListTile extends StatelessWidget {
|
||||
title: Text('blockUser').tr(),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
onTap:
|
||||
() => onUpdateStatus?.call(
|
||||
relationship,
|
||||
-100,
|
||||
),
|
||||
onTap: () => onUpdateStatus?.call(relationship, -100),
|
||||
)
|
||||
else if (relationship.status <= -100) // If blocked
|
||||
PopupMenuItem(
|
||||
@@ -187,9 +181,7 @@ class RelationshipListTile extends StatelessWidget {
|
||||
title: Text('unblockUser').tr(),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
onTap:
|
||||
() =>
|
||||
onUpdateStatus?.call(relationship, 100),
|
||||
onTap: () => onUpdateStatus?.call(relationship, 100),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -299,6 +291,7 @@ class RelationshipScreen extends HookConsumerWidget {
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: PaginationList(
|
||||
padding: EdgeInsets.zero,
|
||||
provider: relationshipListNotifierProvider,
|
||||
notifier: relationshipListNotifierProvider.notifier,
|
||||
itemBuilder: (context, index, relationship) {
|
||||
@@ -380,9 +373,7 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: requests.when(
|
||||
data:
|
||||
(items) =>
|
||||
items.isEmpty
|
||||
data: (items) => items.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
'friendSentRequestEmpty'.tr(),
|
||||
|
||||
@@ -12,7 +12,7 @@ import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/paging/pagination_list.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
final marketplaceWebFeedsNotifierProvider = AsyncNotifierProvider(
|
||||
final marketplaceWebFeedsNotifierProvider = AsyncNotifierProvider.autoDispose(
|
||||
MarketplaceWebFeedsNotifier.new,
|
||||
);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class DiscoveryRealmsScreen extends HookConsumerWidget {
|
||||
children: [
|
||||
CustomScrollView(
|
||||
slivers: [
|
||||
SliverGap(80),
|
||||
SliverGap(88),
|
||||
SliverRealmList(
|
||||
query: currentQuery.value,
|
||||
key: ValueKey(currentQuery.value),
|
||||
|
||||
@@ -163,7 +163,7 @@ class NotificationUnreadCountNotifier
|
||||
}
|
||||
}
|
||||
|
||||
final notificationListProvider = AsyncNotifierProvider(
|
||||
final notificationListProvider = AsyncNotifierProvider.autoDispose(
|
||||
NotificationListNotifier.new,
|
||||
);
|
||||
|
||||
|
||||
@@ -28,9 +28,8 @@ sealed class MarketplaceStickerQuery with _$MarketplaceStickerQuery {
|
||||
}) = _MarketplaceStickerQuery;
|
||||
}
|
||||
|
||||
final marketplaceStickerPacksNotifierProvider = AsyncNotifierProvider(
|
||||
MarketplaceStickerPacksNotifier.new,
|
||||
);
|
||||
final marketplaceStickerPacksNotifierProvider =
|
||||
AsyncNotifierProvider.autoDispose(MarketplaceStickerPacksNotifier.new);
|
||||
|
||||
class MarketplaceStickerPacksNotifier extends AsyncNotifier<List<SnStickerPack>>
|
||||
with
|
||||
|
||||
@@ -112,8 +112,8 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
),
|
||||
),
|
||||
),
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
|
||||
const Gap(16),
|
||||
@@ -137,8 +137,7 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
),
|
||||
),
|
||||
),
|
||||
items:
|
||||
kCurrencyIconData.keys.map((currency) {
|
||||
items: kCurrencyIconData.keys.map((currency) {
|
||||
return DropdownMenuItem(
|
||||
value: currency,
|
||||
child: Row(
|
||||
@@ -178,8 +177,7 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
decoration: InputDecoration(
|
||||
labelText: 'enterNumberOfSplits'.tr(),
|
||||
hintText:
|
||||
selectedRecipients.isNotEmpty
|
||||
hintText: selectedRecipients.isNotEmpty
|
||||
? selectedRecipients.length.toString()
|
||||
: '1',
|
||||
border: OutlineInputBorder(
|
||||
@@ -188,12 +186,12 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
),
|
||||
),
|
||||
),
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
onChanged: (value) {
|
||||
if (value.isEmpty && selectedRecipients.isNotEmpty) {
|
||||
splitsController.text =
|
||||
selectedRecipients.length.toString();
|
||||
splitsController.text = selectedRecipients.length
|
||||
.toString();
|
||||
}
|
||||
},
|
||||
),
|
||||
@@ -261,8 +259,7 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
).colorScheme.outline.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
child:
|
||||
selectedRecipients.isNotEmpty
|
||||
child: selectedRecipients.isNotEmpty
|
||||
? Column(
|
||||
children: [
|
||||
...selectedRecipients.map((recipient) {
|
||||
@@ -283,26 +280,23 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
),
|
||||
subtitle: Text(
|
||||
'selectedRecipient'.tr(),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodySmall?.copyWith(
|
||||
color:
|
||||
Theme.of(
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
onPressed:
|
||||
() => setState(
|
||||
() => selectedRecipients.remove(
|
||||
recipient,
|
||||
),
|
||||
onPressed: () => setState(
|
||||
() =>
|
||||
selectedRecipients.remove(recipient),
|
||||
),
|
||||
icon: Icon(
|
||||
Icons.clear,
|
||||
color:
|
||||
Theme.of(context).colorScheme.error,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.error,
|
||||
),
|
||||
tooltip: 'Remove recipient',
|
||||
),
|
||||
@@ -316,19 +310,16 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
Icon(
|
||||
Icons.person_add_outlined,
|
||||
size: 48,
|
||||
color:
|
||||
Theme.of(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'noRecipientsSelected'.tr(),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodyMedium?.copyWith(
|
||||
color:
|
||||
Theme.of(
|
||||
style: Theme.of(context).textTheme.bodyMedium
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -336,11 +327,9 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
const Gap(4),
|
||||
Text(
|
||||
'selectRecipientsToSendFund'.tr(),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodySmall?.copyWith(
|
||||
color:
|
||||
Theme.of(
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -399,8 +388,8 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
),
|
||||
),
|
||||
maxLines: 3,
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -441,13 +430,10 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
useSafeArea: true,
|
||||
builder:
|
||||
(context) => Container(
|
||||
builder: (context) => Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(16),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
@@ -473,10 +459,10 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
const Gap(24),
|
||||
OtpTextField(
|
||||
numberOfFields: 6,
|
||||
borderColor:
|
||||
Theme.of(context).colorScheme.outline,
|
||||
focusedBorderColor:
|
||||
Theme.of(context).colorScheme.primary,
|
||||
borderColor: Theme.of(context).colorScheme.outline,
|
||||
focusedBorderColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.primary,
|
||||
showFieldAsBox: true,
|
||||
obscureText: true,
|
||||
keyboardType: TextInputType.number,
|
||||
@@ -484,9 +470,7 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
fieldHeight: 56,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderWidth: 1,
|
||||
textStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineSmall
|
||||
textStyle: Theme.of(context).textTheme.headlineSmall
|
||||
?.copyWith(fontWeight: FontWeight.w600),
|
||||
onSubmit: (pin) {
|
||||
enteredPin = pin;
|
||||
@@ -552,8 +536,7 @@ class _CreateFundSheetState extends State<CreateFundSheet> {
|
||||
'split_type': selectedSplitType,
|
||||
'amount_of_splits': splits,
|
||||
'recipient_account_ids': selectedRecipients.map((r) => r.id).toList(),
|
||||
'message':
|
||||
messageController.text.trim().isEmpty
|
||||
'message': messageController.text.trim().isEmpty
|
||||
? null
|
||||
: messageController.text.trim(),
|
||||
'pin_code': '', // Will be filled by PIN verification
|
||||
@@ -632,8 +615,8 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
),
|
||||
),
|
||||
),
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
|
||||
const Gap(16),
|
||||
@@ -657,8 +640,7 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
),
|
||||
),
|
||||
),
|
||||
items:
|
||||
kCurrencyIconData.keys.map((currency) {
|
||||
items: kCurrencyIconData.keys.map((currency) {
|
||||
return DropdownMenuItem(
|
||||
value: currency,
|
||||
child: Row(
|
||||
@@ -702,8 +684,7 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
).colorScheme.outline.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
child:
|
||||
selectedPayee != null
|
||||
child: selectedPayee != null
|
||||
? ListTile(
|
||||
contentPadding: const EdgeInsets.only(
|
||||
left: 20,
|
||||
@@ -721,18 +702,16 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
),
|
||||
subtitle: Text(
|
||||
'selectedPayee'.tr(),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodySmall?.copyWith(
|
||||
color:
|
||||
Theme.of(
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
onPressed:
|
||||
() => setState(() => selectedPayee = null),
|
||||
onPressed: () =>
|
||||
setState(() => selectedPayee = null),
|
||||
icon: Icon(
|
||||
Icons.clear,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
@@ -746,19 +725,16 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
Icon(
|
||||
Icons.person_add_outlined,
|
||||
size: 48,
|
||||
color:
|
||||
Theme.of(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'noPayeeSelected'.tr(),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodyMedium?.copyWith(
|
||||
color:
|
||||
Theme.of(
|
||||
style: Theme.of(context).textTheme.bodyMedium
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -766,11 +742,9 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
const Gap(4),
|
||||
Text(
|
||||
'selectPayeeToTransfer'.tr(),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodySmall?.copyWith(
|
||||
color:
|
||||
Theme.of(
|
||||
style: Theme.of(context).textTheme.bodySmall
|
||||
?.copyWith(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -824,8 +798,8 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
),
|
||||
),
|
||||
maxLines: 3,
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
onTapOutside: (_) =>
|
||||
FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -866,13 +840,10 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
useSafeArea: true,
|
||||
builder:
|
||||
(context) => Container(
|
||||
builder: (context) => Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(16),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
@@ -898,10 +869,10 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
const Gap(24),
|
||||
OtpTextField(
|
||||
numberOfFields: 6,
|
||||
borderColor:
|
||||
Theme.of(context).colorScheme.outline,
|
||||
focusedBorderColor:
|
||||
Theme.of(context).colorScheme.primary,
|
||||
borderColor: Theme.of(context).colorScheme.outline,
|
||||
focusedBorderColor: Theme.of(
|
||||
context,
|
||||
).colorScheme.primary,
|
||||
showFieldAsBox: true,
|
||||
obscureText: true,
|
||||
keyboardType: TextInputType.number,
|
||||
@@ -909,9 +880,7 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
fieldHeight: 56,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderWidth: 1,
|
||||
textStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineSmall
|
||||
textStyle: Theme.of(context).textTheme.headlineSmall
|
||||
?.copyWith(fontWeight: FontWeight.w600),
|
||||
onSubmit: (pin) {
|
||||
enteredPin = pin;
|
||||
@@ -974,8 +943,7 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
'amount': amount,
|
||||
'currency': selectedCurrency,
|
||||
'payee_account_id': selectedPayee!.id,
|
||||
'remark':
|
||||
remarkController.text.trim().isEmpty
|
||||
'remark': remarkController.text.trim().isEmpty
|
||||
? null
|
||||
: remarkController.text.trim(),
|
||||
};
|
||||
@@ -991,7 +959,7 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
|
||||
}
|
||||
}
|
||||
|
||||
final transactionListProvider = AsyncNotifierProvider(
|
||||
final transactionListProvider = AsyncNotifierProvider.autoDispose(
|
||||
TransactionListNotifier.new,
|
||||
);
|
||||
|
||||
@@ -1012,14 +980,17 @@ class TransactionListNotifier extends AsyncNotifier<List<SnTransaction>>
|
||||
);
|
||||
totalCount = int.parse(response.headers.value('X-Total') ?? '0');
|
||||
final List<dynamic> data = response.data;
|
||||
final transactions =
|
||||
data.map((json) => SnTransaction.fromJson(json)).toList();
|
||||
final transactions = data
|
||||
.map((json) => SnTransaction.fromJson(json))
|
||||
.toList();
|
||||
|
||||
return transactions;
|
||||
}
|
||||
}
|
||||
|
||||
final walletFundsProvider = AsyncNotifierProvider(WalletFundsNotifier.new);
|
||||
final walletFundsProvider = AsyncNotifierProvider.autoDispose(
|
||||
WalletFundsNotifier.new,
|
||||
);
|
||||
|
||||
class WalletFundsNotifier extends AsyncNotifier<List<SnWalletFund>>
|
||||
with AsyncPaginationController<SnWalletFund> {
|
||||
@@ -1034,8 +1005,9 @@ class WalletFundsNotifier extends AsyncNotifier<List<SnWalletFund>>
|
||||
'/pass/wallets/funds?offset=$offset&take=$pageSize',
|
||||
);
|
||||
// Assuming total count header is present or we just check if list is empty
|
||||
final list =
|
||||
(response.data as List).map((e) => SnWalletFund.fromJson(e)).toList();
|
||||
final list = (response.data as List)
|
||||
.map((e) => SnWalletFund.fromJson(e))
|
||||
.toList();
|
||||
if (list.length < pageSize) {
|
||||
totalCount = fetchedCount + list.length;
|
||||
}
|
||||
@@ -1043,7 +1015,7 @@ class WalletFundsNotifier extends AsyncNotifier<List<SnWalletFund>>
|
||||
}
|
||||
}
|
||||
|
||||
final walletFundRecipientsProvider = AsyncNotifierProvider(
|
||||
final walletFundRecipientsProvider = AsyncNotifierProvider.autoDispose(
|
||||
WalletFundRecipientsNotifier.new,
|
||||
);
|
||||
|
||||
@@ -1060,8 +1032,7 @@ class WalletFundRecipientsNotifier
|
||||
final response = await client.get(
|
||||
'/pass/wallets/funds/recipients?offset=$offset&take=$_pageSize',
|
||||
);
|
||||
final list =
|
||||
(response.data as List)
|
||||
final list = (response.data as List)
|
||||
.map((e) => SnWalletFundRecipient.fromJson(e))
|
||||
.toList();
|
||||
|
||||
@@ -1312,8 +1283,7 @@ class WalletScreen extends HookConsumerWidget {
|
||||
return allCurrencies.map((currency) {
|
||||
final existingPocket = pockets.firstWhere(
|
||||
(p) => p.currency == currency,
|
||||
orElse:
|
||||
() => SnWalletPocket(
|
||||
orElse: () => SnWalletPocket(
|
||||
id: '',
|
||||
currency: currency,
|
||||
amount: 0.0,
|
||||
@@ -1338,10 +1308,10 @@ class WalletScreen extends HookConsumerWidget {
|
||||
? Symbols.money_bag
|
||||
: Symbols.swap_horiz,
|
||||
),
|
||||
onPressed:
|
||||
currentTabIndex.value == 1 ? createFund : createTransfer,
|
||||
tooltip:
|
||||
currentTabIndex.value == 1
|
||||
onPressed: currentTabIndex.value == 1
|
||||
? createFund
|
||||
: createTransfer,
|
||||
tooltip: currentTabIndex.value == 1
|
||||
? 'createFund'.tr()
|
||||
: 'createTransfer'.tr(),
|
||||
),
|
||||
@@ -1368,8 +1338,7 @@ class WalletScreen extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
return NestedScrollView(
|
||||
headerSliverBuilder:
|
||||
(context, innerBoxIsScrolled) => [
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) => [
|
||||
// Wallet Overview
|
||||
SliverToBoxAdapter(
|
||||
child: Column(
|
||||
@@ -1388,11 +1357,8 @@ class WalletScreen extends HookConsumerWidget {
|
||||
kCurrencyIconData[pocket.currency] ??
|
||||
Symbols.universal_currency_alt,
|
||||
),
|
||||
title:
|
||||
Text(
|
||||
getCurrencyTranslationKey(
|
||||
pocket.currency,
|
||||
),
|
||||
title: Text(
|
||||
getCurrencyTranslationKey(pocket.currency),
|
||||
).tr(),
|
||||
subtitle: Text(
|
||||
'${pocket.amount.toStringAsFixed(2)} ${getCurrencyTranslationKey(pocket.currency, isShort: true).tr()}',
|
||||
@@ -1438,10 +1404,8 @@ class WalletScreen extends HookConsumerWidget {
|
||||
context: context,
|
||||
useRootNavigator: true,
|
||||
isScrollControlled: true,
|
||||
builder:
|
||||
(context) => TransactionDetailSheet(
|
||||
transaction: transaction,
|
||||
),
|
||||
builder: (context) =>
|
||||
TransactionDetailSheet(transaction: transaction),
|
||||
);
|
||||
},
|
||||
child: ListTile(
|
||||
@@ -1479,8 +1443,7 @@ class WalletScreen extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
},
|
||||
error:
|
||||
(error, stackTrace) => ResponseErrorWidget(
|
||||
error: (error, stackTrace) => ResponseErrorWidget(
|
||||
error: error,
|
||||
onRetry: () => ref.invalidate(walletCurrentProvider),
|
||||
),
|
||||
@@ -1554,8 +1517,9 @@ class WalletScreen extends HookConsumerWidget {
|
||||
itemCount: fundList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final fund = fundList[index];
|
||||
final claimedCount =
|
||||
fund.recipients.where((r) => r.isReceived).length;
|
||||
final claimedCount = fund.recipients
|
||||
.where((r) => r.isReceived)
|
||||
.length;
|
||||
final totalRecipients = fund.recipients.length;
|
||||
|
||||
return Card(
|
||||
@@ -1724,16 +1688,14 @@ class WalletScreen extends HookConsumerWidget {
|
||||
),
|
||||
);
|
||||
},
|
||||
loading:
|
||||
() => Card(
|
||||
loading: () => Card(
|
||||
margin: EdgeInsets.zero,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
),
|
||||
error:
|
||||
(error, stack) => Card(
|
||||
error: (error, stack) => Card(
|
||||
margin: EdgeInsets.zero,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/realm.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/pods/paging.dart';
|
||||
import 'package:island/widgets/paging/pagination_list.dart';
|
||||
import 'package:island/widgets/realm/realm_card.dart';
|
||||
import 'package:island/widgets/realm/realm_list_tile.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
final realmListNotifierProvider = AsyncNotifierProvider.autoDispose
|
||||
@@ -51,25 +50,12 @@ class SliverRealmList extends HookConsumerWidget {
|
||||
notifier: provider.notifier,
|
||||
isSliver: true,
|
||||
isRefreshable: false,
|
||||
spacing: 8,
|
||||
itemBuilder: (context, index, realm) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child:
|
||||
ConstrainedBox(
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 540),
|
||||
child: RealmCard(realm: realm),
|
||||
).center(),
|
||||
),
|
||||
if (index <
|
||||
(ref.read(provider).value?.length ?? 0) -
|
||||
1) // Add gap except for last item? Actually PaginationList handles loading indicator which might look like last item.
|
||||
// Wait, ref.read(provider).value?.length might change.
|
||||
// Simpler to just add bottom padding to all, or Gap.
|
||||
const Gap(8),
|
||||
],
|
||||
);
|
||||
child: RealmListTile(realm: realm),
|
||||
).center();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user