make swap scrollable on smaller devices (#3139)
malik1004x committed
Mar 27, 2026 at 16:50 UTC
ba9e8d7b7fb188e35da92a485e60b186d28993dc
1 file changed
+131
-125
lib/new-ui/pages/swap_page.dart
+131
-125
@@ -481,134 +481,140 @@ class _NewSwapPageState extends State<NewSwapPage> {
481
mainAxisAlignment: MainAxisAlignment.spaceBetween,
482
mainAxisSize: MainAxisSize.max,
483
children: [
484
- RepaintBoundary(
485
- child: Form(
486
- key: formKey,
487
- child: Column(
488
- children: [
489
- Observer(
490
- builder: (_) => SwapAmountBox(
491
- isReceiverCard: false,
492
- walletSwitcherViewModel: widget.walletSwitcherViewModel,
493
- exchangeViewModel: widget.exchangeViewModel,
494
- onDispose: disposeBestRateSync,
495
- hasAllAmount: widget.exchangeViewModel.hasAllAmount,
496
- allAmount: widget.exchangeViewModel.hasAllAmount
497
- ? () => widget.exchangeViewModel.enableSendAllAmount()
498
- : null,
499
- key: depositKey,
500
- title: S.of(context).send,
501
- initialCurrency: widget.exchangeViewModel.depositCurrency,
502
- hasRefundAddress: true,
503
- currencies: widget.exchangeViewModel.depositCurrencies,
504
- onCurrencySelected: (currency) {
505
- if (currency is CryptoCurrency) {
506
- widget.exchangeViewModel
507
- .changeDepositCurrency(currency: currency);
508
- }
509
- },
510
- currencyValueValidator: (value) {
511
- return !widget.exchangeViewModel.isFixedRateMode &&
512
- value != S.of(context).all
513
- ? AmountValidator(
514
- isAutovalidate: true,
515
- currency: widget.exchangeViewModel.isFixedRateMode
516
- ? widget.exchangeViewModel.receiveCurrency
517
- : widget.exchangeViewModel.depositCurrency,
518
- minValue: widget.exchangeViewModel.limits.min.toString(),
519
- maxValue: widget.exchangeViewModel.limits.max.toString(),
520
- amountParsingProxy:
521
- widget.exchangeViewModel.amountParsingProxy,
522
- ).call(value)
523
- : null;
524
- },
525
- addressTextFieldValidator: AddressValidator(
526
- type: widget.exchangeViewModel.depositCurrency),
527
- onPushPasteButton: (context) async {
528
- final clipboard = await Clipboard.getData('text/plain');
529
- widget.exchangeViewModel.depositAddress = clipboard?.text ?? '';
530
-
531
- final domain = widget.exchangeViewModel.depositAddress;
532
- widget.exchangeViewModel.depositAddress =
533
- await fetchParsedAddress(context, domain,
534
- widget.exchangeViewModel.depositCurrency);
535
- },
536
- onPushAddressBookButton: (context) async {
537
- final domain = widget.exchangeViewModel.depositAddress;
538
- widget.exchangeViewModel.depositAddress =
539
- await fetchParsedAddress(context, domain,
540
- widget.exchangeViewModel.depositCurrency);
541
- },
542
- ),
543
- ),
544
- SwapLimitPopup(exchangeViewModel: widget.exchangeViewModel),
545
- Padding(
546
- padding: const EdgeInsets.symmetric(vertical: 12.0),
547
- child: Stack(
548
- alignment: Alignment.center,
549
- children: [
550
- Container(
551
- height: 1,
552
- width: double.infinity,
553
- color: Theme.of(context).colorScheme.surfaceContainerHigh,
484
+ Expanded(
485
+ child: RepaintBoundary(
486
+ child: Form(
487
+ key: formKey,
488
+ child: SingleChildScrollView(
489
+ physics: ClampingScrollPhysics(),
490
+ controller: ModalScrollController.of(context),
491
+ child: Column(
492
+ children: [
493
+ Observer(
494
+ builder: (_) => SwapAmountBox(
495
+ isReceiverCard: false,
496
+ walletSwitcherViewModel: widget.walletSwitcherViewModel,
497
+ exchangeViewModel: widget.exchangeViewModel,
498
+ onDispose: disposeBestRateSync,
499
+ hasAllAmount: widget.exchangeViewModel.hasAllAmount,
500
+ allAmount: widget.exchangeViewModel.hasAllAmount
501
+ ? () => widget.exchangeViewModel.enableSendAllAmount()
502
+ : null,
503
+ key: depositKey,
504
+ title: S.of(context).send,
505
+ initialCurrency: widget.exchangeViewModel.depositCurrency,
506
+ hasRefundAddress: true,
507
+ currencies: widget.exchangeViewModel.depositCurrencies,
508
+ onCurrencySelected: (currency) {
509
+ if (currency is CryptoCurrency) {
510
+ widget.exchangeViewModel
511
+ .changeDepositCurrency(currency: currency);
512
+ }
513
+ },
514
+ currencyValueValidator: (value) {
515
+ return !widget.exchangeViewModel.isFixedRateMode &&
516
+ value != S.of(context).all
517
+ ? AmountValidator(
518
+ isAutovalidate: true,
519
+ currency: widget.exchangeViewModel.isFixedRateMode
520
+ ? widget.exchangeViewModel.receiveCurrency
521
+ : widget.exchangeViewModel.depositCurrency,
522
+ minValue: widget.exchangeViewModel.limits.min.toString(),
523
+ maxValue: widget.exchangeViewModel.limits.max.toString(),
524
+ amountParsingProxy:
525
+ widget.exchangeViewModel.amountParsingProxy,
526
+ ).call(value)
527
+ : null;
528
+ },
529
+ addressTextFieldValidator: AddressValidator(
530
+ type: widget.exchangeViewModel.depositCurrency),
531
+ onPushPasteButton: (context) async {
532
+ final clipboard = await Clipboard.getData('text/plain');
533
+ widget.exchangeViewModel.depositAddress = clipboard?.text ?? '';
534
+
535
+ final domain = widget.exchangeViewModel.depositAddress;
536
+ widget.exchangeViewModel.depositAddress =
537
+ await fetchParsedAddress(context, domain,
538
+ widget.exchangeViewModel.depositCurrency);
539
+ },
540
+ onPushAddressBookButton: (context) async {
541
+ final domain = widget.exchangeViewModel.depositAddress;
542
+ widget.exchangeViewModel.depositAddress =
543
+ await fetchParsedAddress(context, domain,
544
+ widget.exchangeViewModel.depositCurrency);
545
+ },
546
),
555
- ModernButton.svg(
556
- size: 36,
557
- iconSize: 24,
558
- svgPath: "assets/new-ui/swap_amounts.svg",
559
- onPressed: widget.exchangeViewModel.reverseSwapDirection,
547
+ ),
548
+ SwapLimitPopup(exchangeViewModel: widget.exchangeViewModel),
549
+ Padding(
550
+ padding: const EdgeInsets.symmetric(vertical: 12.0),
551
+ child: Stack(
552
+ alignment: Alignment.center,
553
+ children: [
554
+ Container(
555
+ height: 1,
556
+ width: double.infinity,
557
+ color: Theme.of(context).colorScheme.surfaceContainerHigh,
558
+ ),
559
+ ModernButton.svg(
560
+ size: 36,
561
+ iconSize: 24,
562
+ svgPath: "assets/new-ui/swap_amounts.svg",
563
+ onPressed: widget.exchangeViewModel.reverseSwapDirection,
564
+ ),
565
+ ],
566
),
561
- ],
562
- ),
567
+ ),
568
+ Observer(
569
+ builder: (_) => SwapAmountBox(
570
+ isReceiverCard: true,
571
+ walletSwitcherViewModel: widget.walletSwitcherViewModel,
572
+ exchangeViewModel: widget.exchangeViewModel,
573
+ onDispose: disposeBestRateSync,
574
+ key: receiveKey,
575
+ title: S.of(context).receive,
576
+ initialCurrency: widget.exchangeViewModel.receiveCurrency,
577
+ currencies: widget.exchangeViewModel.receiveCurrencies,
578
+ onCurrencySelected: (currency) {
579
+ if (currency is CryptoCurrency) {
580
+ widget.exchangeViewModel
581
+ .changeReceiveCurrency(currency: currency);
582
+ }
583
+ },
584
+ currencyValueValidator: (value) {
585
+ return widget.exchangeViewModel.isFixedRateMode
586
+ ? AmountValidator(
587
+ isAutovalidate: true,
588
+ currency: widget.exchangeViewModel.receiveCurrency,
589
+ minValue: widget.exchangeViewModel.limits.min.toString(),
590
+ maxValue: widget.exchangeViewModel.limits.max.toString(),
591
+ amountParsingProxy:
592
+ widget.exchangeViewModel.amountParsingProxy,
593
+ ).call(value)
594
+ : null;
595
+ },
596
+ addressTextFieldValidator: AddressValidator(
597
+ type: widget.exchangeViewModel.receiveCurrency),
598
+ onPushPasteButton: (context) async {
599
+ final clipboard = await Clipboard.getData('text/plain');
600
+ widget.exchangeViewModel.receiveAddress = clipboard?.text ?? '';
601
+
602
+ final domain = widget.exchangeViewModel.receiveAddress;
603
+ widget.exchangeViewModel.receiveAddress =
604
+ await fetchParsedAddress(context, domain,
605
+ widget.exchangeViewModel.receiveCurrency);
606
+ },
607
+ onPushAddressBookButton: (context) async {
608
+ final domain = widget.exchangeViewModel.receiveAddress;
609
+ widget.exchangeViewModel.receiveAddress =
610
+ await fetchParsedAddress(context, domain,
611
+ widget.exchangeViewModel.receiveCurrency);
612
+ },
613
+ ),
614
+ )
615
+ ],
616
),
564
- Observer(
565
- builder: (_) => SwapAmountBox(
566
- isReceiverCard: true,
567
- walletSwitcherViewModel: widget.walletSwitcherViewModel,
568
- exchangeViewModel: widget.exchangeViewModel,
569
- onDispose: disposeBestRateSync,
570
- key: receiveKey,
571
- title: S.of(context).receive,
572
- initialCurrency: widget.exchangeViewModel.receiveCurrency,
573
- currencies: widget.exchangeViewModel.receiveCurrencies,
574
- onCurrencySelected: (currency) {
575
- if (currency is CryptoCurrency) {
576
- widget.exchangeViewModel
577
- .changeReceiveCurrency(currency: currency);
578
- }
579
- },
580
- currencyValueValidator: (value) {
581
- return widget.exchangeViewModel.isFixedRateMode
582
- ? AmountValidator(
583
- isAutovalidate: true,
584
- currency: widget.exchangeViewModel.receiveCurrency,
585
- minValue: widget.exchangeViewModel.limits.min.toString(),
586
- maxValue: widget.exchangeViewModel.limits.max.toString(),
587
- amountParsingProxy:
588
- widget.exchangeViewModel.amountParsingProxy,
589
- ).call(value)
590
- : null;
591
- },
592
- addressTextFieldValidator: AddressValidator(
593
- type: widget.exchangeViewModel.receiveCurrency),
594
- onPushPasteButton: (context) async {
595
- final clipboard = await Clipboard.getData('text/plain');
596
- widget.exchangeViewModel.receiveAddress = clipboard?.text ?? '';
597
-
598
- final domain = widget.exchangeViewModel.receiveAddress;
599
- widget.exchangeViewModel.receiveAddress =
600
- await fetchParsedAddress(context, domain,
601
- widget.exchangeViewModel.receiveCurrency);
602
- },
603
- onPushAddressBookButton: (context) async {
604
- final domain = widget.exchangeViewModel.receiveAddress;
605
- widget.exchangeViewModel.receiveAddress =
606
- await fetchParsedAddress(context, domain,
607
- widget.exchangeViewModel.receiveCurrency);
608
- },
609
- ),
610
- )
611
- ],
617
+ ),
618
),
619
),
620
),