mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
CW-1190: Minor Fixes (#2614)
* fix: Enhance WalletConnect URI handling and validation, better handle errors * fix: Disable swipe to send if wallet is not synchronized * fix: Handle session expiry gracefully * fix: Disable swipe to send if wallet is not synced
This commit is contained in:
@@ -627,6 +627,7 @@ class CakePayBuyCardPage extends BasePage {
|
||||
feeFiatAmount: _sendViewModel.pendingTransactionFeeFiatAmountFormatted,
|
||||
outputs: displayingOutputs,
|
||||
footerType: FooterType.slideActionButton,
|
||||
isSlideActionEnabled: _sendViewModel.isReadyForSend,
|
||||
slideActionButtonText:
|
||||
cakePayBuyCardViewModel.isSimulating ? 'Swipe to simulate' : 'Swipe to send',
|
||||
accessibleNavigationModeSlideActionButtonText:
|
||||
|
||||
@@ -284,6 +284,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
||||
return ConfirmSendingBottomSheet(
|
||||
key: ValueKey('exchange_trade_page_confirm_sending_bottom_sheet_key'),
|
||||
footerType: FooterType.slideActionButton,
|
||||
isSlideActionEnabled: widget.exchangeTradeViewModel.sendViewModel.isReadyForSend,
|
||||
walletType: widget.exchangeTradeViewModel.sendViewModel.walletType,
|
||||
titleText: S.of(bottomSheetContext).confirm_transaction,
|
||||
titleIconPath:
|
||||
|
||||
@@ -567,6 +567,7 @@ class SendPage extends BasePage {
|
||||
titleText: S.of(bottomSheetContext).confirm_transaction,
|
||||
accessibleNavigationModeSlideActionButtonText: S.of(bottomSheetContext).send,
|
||||
footerType: FooterType.slideActionButton,
|
||||
isSlideActionEnabled: sendViewModel.isReadyForSend,
|
||||
walletType: sendViewModel.walletType,
|
||||
titleIconPath: sendViewModel.selectedCryptoCurrency.iconPath,
|
||||
currency: sendViewModel.selectedCryptoCurrency,
|
||||
|
||||
@@ -190,6 +190,7 @@ class RBFDetailsPage extends BasePage {
|
||||
return ConfirmSendingBottomSheet(
|
||||
key: ValueKey('rbf_confirm_sending_bottom_sheet'),
|
||||
titleText: S.of(bottomSheetContext).confirm_transaction,
|
||||
isSlideActionEnabled: transactionDetailsViewModel.sendViewModel.isReadyForSend,
|
||||
walletType: transactionDetailsViewModel.sendViewModel.walletType,
|
||||
titleIconPath:
|
||||
transactionDetailsViewModel.sendViewModel.selectedCryptoCurrency.iconPath,
|
||||
|
||||
@@ -202,6 +202,13 @@ abstract class WalletKitServiceBase with Store {
|
||||
),
|
||||
);
|
||||
}
|
||||
} on ReownSignError catch (e) {
|
||||
if (e.code == 6) {
|
||||
try {
|
||||
await deletePairing(topic: session.pairingTopic);
|
||||
} catch (_) {}
|
||||
_refreshPairings();
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,13 @@ class WalletConnectConnectionsView extends StatelessWidget {
|
||||
|
||||
final query = actualLinkList[1];
|
||||
|
||||
final uri = Uri.decodeComponent(query);
|
||||
final decoded = Uri.decodeComponent(query).trim();
|
||||
|
||||
final uriData = Uri.parse(uri);
|
||||
final sanitized = decoded.startsWith('@') ? decoded.substring(1) : decoded;
|
||||
|
||||
final uriData = Uri.tryParse(sanitized);
|
||||
|
||||
if (uriData == null || (uriData.scheme.isEmpty)) return;
|
||||
|
||||
await walletKitService.pairWithUri(uriData);
|
||||
}
|
||||
@@ -88,7 +92,25 @@ class WCPairingsWidget extends BasePage {
|
||||
if (walletConnectURI == null) return _invalidUriToast(context, S.current.nullURIError);
|
||||
|
||||
log('_onFoundUri: $walletConnectURI');
|
||||
final Uri uriData = Uri.parse(walletConnectURI);
|
||||
// Accept either a raw WC URI or a full URL containing `uri=` parameter
|
||||
String input = walletConnectURI.trim();
|
||||
|
||||
if (input.contains('uri=')) {
|
||||
final parts = input.split('uri=');
|
||||
if (parts.length > 1) {
|
||||
input = Uri.decodeComponent(parts.last);
|
||||
}
|
||||
}
|
||||
|
||||
// Some scanners may prefix with '@', strip it
|
||||
if (input.startsWith('@')) {
|
||||
input = input.substring(1);
|
||||
}
|
||||
final Uri? uriData = Uri.tryParse(input);
|
||||
final bool hasValidScheme = uriData != null && uriData.scheme.isNotEmpty;
|
||||
if (!hasValidScheme) {
|
||||
return _invalidUriToast(context, S.current.invalid_input);
|
||||
}
|
||||
await walletKitService.pairWithUri(uriData);
|
||||
}
|
||||
|
||||
@@ -121,10 +143,10 @@ class WCPairingsWidget extends BasePage {
|
||||
Text(
|
||||
S.current.connectWalletPrompt,
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
PrimaryButton(
|
||||
@@ -156,10 +178,10 @@ class WCPairingsWidget extends BasePage {
|
||||
S.current.activeConnectionsPrompt,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
replacement: ListView.builder(
|
||||
|
||||
@@ -12,6 +12,7 @@ abstract class BaseBottomSheet extends StatelessWidget {
|
||||
required this.footerType,
|
||||
this.slideActionButtonText,
|
||||
this.onSlideActionComplete,
|
||||
this.isSlideActionEnabled = true,
|
||||
this.singleActionButtonText,
|
||||
this.accessibleNavigationModeSlideActionButtonText,
|
||||
this.onSingleActionButtonPressed,
|
||||
@@ -30,6 +31,7 @@ abstract class BaseBottomSheet extends StatelessWidget {
|
||||
final FooterType footerType;
|
||||
final String? slideActionButtonText;
|
||||
final VoidCallback? onSlideActionComplete;
|
||||
final bool isSlideActionEnabled;
|
||||
final String? singleActionButtonText;
|
||||
final String? accessibleNavigationModeSlideActionButtonText;
|
||||
final VoidCallback? onSingleActionButtonPressed;
|
||||
@@ -112,6 +114,7 @@ abstract class BaseBottomSheet extends StatelessWidget {
|
||||
buttonText: slideActionButtonText ?? '',
|
||||
onSlideComplete: onSlideActionComplete ?? () {},
|
||||
accessibleNavigationModeButtonText: accessibleNavigationModeSlideActionButtonText ?? '',
|
||||
isDisabled: !isSlideActionEnabled,
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
|
||||
String? titleIconPath,
|
||||
String? slideActionButtonText,
|
||||
VoidCallback? onSlideActionComplete,
|
||||
bool isSlideActionEnabled = true,
|
||||
String? accessibleNavigationModeSlideActionButtonText,
|
||||
required this.currency,
|
||||
this.paymentId,
|
||||
@@ -48,6 +49,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
|
||||
footerType: footerType,
|
||||
slideActionButtonText: slideActionButtonText ?? 'Swipe to send',
|
||||
onSlideActionComplete: onSlideActionComplete,
|
||||
isSlideActionEnabled: isSlideActionEnabled,
|
||||
accessibleNavigationModeSlideActionButtonText:
|
||||
accessibleNavigationModeSlideActionButtonText,
|
||||
key: key);
|
||||
|
||||
@@ -11,6 +11,7 @@ class StandardSlideButton extends StatefulWidget {
|
||||
required this.accessibleNavigationModeButtonText,
|
||||
this.tileBackgroundColor,
|
||||
this.knobColor,
|
||||
this.isDisabled = false,
|
||||
}) : super(key: key);
|
||||
|
||||
final VoidCallback onSlideComplete;
|
||||
@@ -19,6 +20,7 @@ class StandardSlideButton extends StatefulWidget {
|
||||
final String accessibleNavigationModeButtonText;
|
||||
final Color? tileBackgroundColor;
|
||||
final Color? knobColor;
|
||||
final bool isDisabled;
|
||||
|
||||
@override
|
||||
StandardSlideButtonState createState() => StandardSlideButtonState();
|
||||
@@ -36,14 +38,16 @@ class StandardSlideButtonState extends State<StandardSlideButton> {
|
||||
Widget build(BuildContext context) {
|
||||
final bool accessible = MediaQuery.of(context).accessibleNavigation;
|
||||
|
||||
final tileBackgroundColor = context.currentTheme.customColors.backgroundGradientColor;
|
||||
final tileBackgroundColor = widget.isDisabled
|
||||
? context.currentTheme.customColors.backgroundGradientColor.withOpacity(0.5)
|
||||
: context.currentTheme.customColors.backgroundGradientColor;
|
||||
|
||||
return accessible
|
||||
? PrimaryButton(
|
||||
text: widget.accessibleNavigationModeButtonText,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||
onPressed: () => widget.onSlideComplete(),
|
||||
onPressed: widget.isDisabled ? null : () => widget.onSlideComplete(),
|
||||
)
|
||||
: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
@@ -56,7 +60,10 @@ class StandardSlideButtonState extends State<StandardSlideButton> {
|
||||
height: widget.height,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: widget.tileBackgroundColor ?? tileBackgroundColor,
|
||||
color: (widget.isDisabled
|
||||
? widget.tileBackgroundColor?.withOpacity(0.5)
|
||||
: widget.tileBackgroundColor) ??
|
||||
tileBackgroundColor,
|
||||
),
|
||||
child: Stack(
|
||||
alignment: Alignment.centerLeft,
|
||||
@@ -74,22 +81,26 @@ class StandardSlideButtonState extends State<StandardSlideButton> {
|
||||
left: sideMargin + _dragPosition,
|
||||
child: GestureDetector(
|
||||
key: ValueKey('standard_slide_button_widget_slider_key'),
|
||||
onHorizontalDragUpdate: (details) {
|
||||
setState(() {
|
||||
_dragPosition += details.delta.dx;
|
||||
if (_dragPosition < 0) _dragPosition = 0;
|
||||
if (_dragPosition > effectiveMaxWidth - sliderWidth) {
|
||||
_dragPosition = effectiveMaxWidth - sliderWidth;
|
||||
}
|
||||
});
|
||||
},
|
||||
onHorizontalDragEnd: (details) {
|
||||
if (_dragPosition >= effectiveMaxWidth - sliderWidth - 10) {
|
||||
widget.onSlideComplete();
|
||||
} else {
|
||||
setState(() => _dragPosition = 0);
|
||||
}
|
||||
},
|
||||
onHorizontalDragUpdate: widget.isDisabled
|
||||
? null
|
||||
: (details) {
|
||||
setState(() {
|
||||
_dragPosition += details.delta.dx;
|
||||
if (_dragPosition < 0) _dragPosition = 0;
|
||||
if (_dragPosition > effectiveMaxWidth - sliderWidth) {
|
||||
_dragPosition = effectiveMaxWidth - sliderWidth;
|
||||
}
|
||||
});
|
||||
},
|
||||
onHorizontalDragEnd: widget.isDisabled
|
||||
? null
|
||||
: (details) {
|
||||
if (_dragPosition >= effectiveMaxWidth - sliderWidth - 10) {
|
||||
widget.onSlideComplete();
|
||||
} else {
|
||||
setState(() => _dragPosition = 0);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
key: ValueKey('standard_slide_button_widget_slider_container_key'),
|
||||
width: sliderWidth,
|
||||
|
||||
Reference in New Issue
Block a user