Add Radar to Apps screen (#3366)

* Add Radar to Apps screen

* ignore flutter error [skip ci]
This commit is contained in:
Omar Hatem
2026-07-11 04:57:54 +03:00
committed by GitHub
parent f4b17e3354
commit 38acc625f0
8 changed files with 65 additions and 21 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

+7
View File
@@ -7,6 +7,13 @@ abstract class PaymentURI {
final String address;
}
class ExternalAddressURI extends PaymentURI {
ExternalAddressURI({required super.amount, required super.address});
@override
String toString() => address;
}
class MoneroURI extends PaymentURI {
MoneroURI({required super.amount, required super.address});
@@ -5,13 +5,12 @@ import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/utils/address_formatter.dart';
import 'package:cake_wallet/utils/clipboard_util.dart';
import 'package:cake_wallet/view_model/send/send_view_model.dart';
import 'package:cw_core/payment_uris.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import "package:cw_core/wallet_type.dart";
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
class L2SendExternalModal extends StatefulWidget {
const L2SendExternalModal({super.key, required this.sendViewModel});
@@ -180,11 +179,7 @@ class _L2SendExternalModalState extends State<L2SendExternalModal> {
children: [
Flexible(
child: NewPrimaryButton(
onPressed:(){
Clipboard.setData(
ClipboardData(text: output.address),
);
},
onPressed: () => ClipboardUtil.copyToClipboard(context, output.address),
text: S.of(context).copy,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary),
@@ -4,11 +4,11 @@ import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
import 'package:cake_wallet/new-ui/widgets/swap_page/swap_modal_header.dart';
import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
import 'package:cake_wallet/utils/address_formatter.dart';
import 'package:cake_wallet/utils/clipboard_util.dart';
import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/payment_uris.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class SwapSendExternalModal extends StatefulWidget {
const SwapSendExternalModal(
@@ -45,7 +45,7 @@ class _SwapSendExternalModalState extends State<SwapSendExternalModal> {
@override
Widget build(BuildContext context) {
if (uri == null) return SizedBox.shrink();
if (widget.address.isEmpty) return SizedBox.shrink();
final resolvedSize = MediaQuery.of(context).size.width * (largeQrMode ? 0.8 : 0.54);
return PopScope(
@@ -139,7 +139,7 @@ class _SwapSendExternalModalState extends State<SwapSendExternalModal> {
child: QrImage(
size: animatedSize,
embeddedImagePath: widget.from.iconPath,
data: uri.toString(),
data: uri?.toString() ?? widget.address,
),
),
);
@@ -175,7 +175,7 @@ class _SwapSendExternalModalState extends State<SwapSendExternalModal> {
children: [
Flexible(
child: NewPrimaryButton(
onPressed: ()=> Clipboard.setData(ClipboardData(text:widget.address)),
onPressed: () => ClipboardUtil.copyToClipboard(context, widget.address),
text: S.of(context).copy,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary),
@@ -148,6 +148,15 @@ class CakeFeaturesPage extends StatelessWidget {
subTitle: "Turn your old phone into your new hardware wallet with our new app",
image: 'assets/images/cupcake.png',
),
AppsWidget(
isWide: true,
isLink: true,
isCake: true,
onTap: () => _launchUrl("radar.chat"),
title: "Radar",
subTitle: "Your messages. Your Bitcoin. Together, at last",
image: 'assets/images/radar.png',
),
const SizedBox(height: 12),
Padding(
padding: const EdgeInsets.only(left: 24, top: 16, bottom: 8),
+18 -2
View File
@@ -1,6 +1,8 @@
import 'package:flutter/services.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sensitive_clipboard/sensitive_clipboard.dart';
class ClipboardUtil {
@@ -12,4 +14,18 @@ class ClipboardUtil {
return Clipboard.setData(data);
}
/// Copies [text] to the clipboard and shows a "Copied to Clipboard"
/// confirmation toast. Prefer this for any user-facing copy action so the
/// feedback stays consistent across the app.
static Future<void> copyToClipboard(
BuildContext context,
String text, {
bool isSensitive = false,
}) async {
await setSensitiveDataToClipboard(ClipboardData(text: text), isSensitive: isSensitive);
if (context.mounted) {
showBar<void>(context, S.of(context).copied_to_clipboard);
}
}
}
+18 -5
View File
@@ -299,14 +299,15 @@ class ExceptionHandler {
"FocusScopeNode was used after being disposed",
"_getDismissibleFlushbar",
"_QueuedFuture.execute (package:universal_ble/src/queue.dart:65)",
"Pending Request Canceled | RequestQueue disposed",
"reown_core/relay_client/websocket/websocket_handler.dart",
"Image upload failed due to loss of GPU access",
"transport error",
"SdkError.sparkError(field0: Operator RPC error: Connection error: status: Unavailable, message: \"dns error\", details: []",
"the timeout of the request was reached",
"support for coin removed, your seedphrase:"
"Exception: Invalid image data"
"support for coin removed, your seedphrase:",
"Exception: Invalid image data",
];
static Future<void> _addDeviceInfo(File file) async {
@@ -441,8 +442,20 @@ class ExceptionHandler {
}
static bool _flutterErrorIgnore(FlutterErrorDetails errorDetails) {
// most probably a flutter context error so just ignore it if there is no stack we can debug with
return errorDetails.exception.toString().contains("Null check operator used on a null value") &&
errorDetails.stack == null;
if (errorDetails.exception.toString().contains("Null check operator used on a null value")) {
// Most probably a flutter context error so just ignore it if there is no
// stack we can debug with.
if (errorDetails.stack == null) {
return true;
}
final stack = errorDetails.stack.toString();
if (stack.contains("handleFocusHighlightModeChange") ||
stack.contains("_HighlightModeManager")) {
return true;
}
}
return false;
}
}
@@ -415,9 +415,13 @@ abstract class ExchangeTradeViewModelBase with Store {
return null;
}
// Using trade currency here so the external-send QR encodes the correct scheme
final uriWalletType =
cryptoCurrencyOrTokenToWalletType(fromCurrency) ?? wallet.type;
// Using the trade's `from` currency so the external-send QR encodes the correct scheme.
final uriWalletType = cryptoCurrencyOrTokenToWalletType(fromCurrency);
// for other currencies that we don't have wallets for
if (uriWalletType == null) {
return ExternalAddressURI(address: inputAddress, amount: amount);
}
printV(uriWalletType);