Files
hash-wallet/lib/new-ui/widgets/apps_widget.dart
T
jwinterm dd449f2594 Merge upstream Cake Wallet v6.5.0
Catches up from the May 12 fork point (v6.1.2+23) through v6.5.0: 535
upstream commits, including the Monero silent-open fix, Monero on Trezor,
Ledger/Trezor BLE fixes, the new seed and history screens, quick Bitcoin
sync, git-pinned dependencies (pubspec_overrides.yaml), frozen Hive
adapters (*.part.dart), monero_c v0.18.4.6-RC2 and Flutter 3.41.9.

Merged with both sides normalized first (import rename, 100-column
format), which took the conflict count from 614 paths to 322. The
procedure is now scripts/upstream_sync.sh.

Kept from Hash Bags:
- WalletType enum order and Hive IDs. SQLite stores WalletType.index and
  our order differs from upstream's; taking theirs would reread saved
  wallets as other chains. Our frozen adapter keeps the shipped IDs.
- The 1.0.2 legacy PIN and wallet-password decode and self-heal.
- Removed chains (Solana, Tron, Zano, Zcash, Decred, Haven) and the new
  Robinhood chain stay out; Cake Pay and non-Trocador swaps stay out.
- Default nodes (node.wownero.org, sethforprivacy, Blockstream, bysh.me),
  converted to upstream's isDefault node-list key; Wownero is back in the
  node reset list.
- Privacy: address resolvers limited to domain-anchored sources again;
  prices.neroswap.com for fiat; upstream's charts tab, which reads
  prices.cakewallet.com, sits behind FeatureFlag.isChartsEnabled = false.
- Lightning stays behind FeatureFlag.isLightningEnabled, including
  upstream's new post-seed Lightning username step.
- Our icon pipeline, branding and bundle identifiers.

Twelve new upstream widget tests are skipped: test and code are unchanged
from v6.5.0 apart from renames (not rerun on a pristine upstream checkout;
upstream's top_bar_test does not compile against its own TopBar).
flutter analyze lib: 0 errors; flutter test: 345 passed, 12 skipped;
flutter build bundle compiles. Built with Flutter 3.41.9.
2026-10-24 23:49:29 -04:00

162 lines
5.8 KiB
Dart

import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/src/widgets/hash_image_widget.dart';
import 'package:hash_wallet/themes/core/theme_extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class AppsWidget extends StatelessWidget {
AppsWidget({
this.onTap,
required this.title,
required this.subTitle,
this.hint,
this.svgPicture,
this.image,
this.icon,
this.onClose,
this.customBorder,
this.shadowSpread,
this.shadowBlur,
super.key,
this.marginV,
this.marginH,
this.isWide,
this.isLink,
this.isCake,
});
final VoidCallback? onTap;
final VoidCallback? onClose;
final String title;
final String subTitle;
final Widget? hint;
final SvgPicture? svgPicture;
final Widget? icon;
final String? image;
final double? customBorder;
final double? marginV;
final double? marginH;
final double? shadowSpread;
final double? shadowBlur;
final bool? isWide;
final bool? isLink;
final bool? isCake;
@override
Widget build(BuildContext context) {
if (isWide == true) {
return Stack(
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: marginH ?? 20, vertical: marginV ?? 5),
width: double.infinity,
decoration: ShapeDecoration(
shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(18)),
gradient: LinearGradient(
colors: [
context.customColors.cardGradientColorPrimary,
context.customColors.cardGradientColorSecondary,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
// The card is one node; the arrow glyph's "leaves the app" meaning
// becomes a hint instead of an unlabeled icon.
child: MergeSemantics(
child: Semantics(
hint: isLink == true ? S.of(context).opens_externally : null,
child: TextButton(
onPressed: onTap,
style: TextButton.styleFrom(
shape: RoundedSuperellipseBorder(
borderRadius: BorderRadius.circular(18),
side: BorderSide(
width: 1.25, color: Theme.of(context).colorScheme.surfaceContainerHigh),
),
padding: EdgeInsets.all(24),
),
child: Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 20),
child: ExcludeSemantics(
child: HashImageWidget(imageUrl: image, height: 54, width: 54),
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
spacing: 6.0,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.w800,
fontSize: 20,
),
softWrap: true,
),
SizedBox(),
],
),
SizedBox(height: 5),
Text(
subTitle,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
fontWeight: FontWeight.w500,
),
softWrap: true,
),
],
),
),
ExcludeSemantics(
child: Icon(
isLink == true ? Icons.arrow_outward : Icons.arrow_forward_ios,
color: Theme.of(context).colorScheme.onSurfaceVariant,
size: 20,
),
)
],
),
if (hint != null) ...[
SizedBox(height: 10),
hint!,
]
],
),
),
),
),
),
if (onClose != null)
Positioned(
top: 10,
right: 10,
// Label the icon-only button without adding a visible tooltip.
child: MergeSemantics(
child: Semantics(
label: S.of(context).close,
child: IconButton(
icon: Icon(Icons.close),
onPressed: onClose,
//color: Theme.of(context).colorScheme.onSurface,
),
),
),
),
],
);
} else {
return Stack();
}
}
}