Cw 973 in app gift card redemption flow plus UI (#2285)

* refactor: cleanup cake_pay folder

* refactor: add My Cards tab on the main screen

* ui: add user card item

* refactor: cakePay purchase flow

* feat: add user card info

* refactor: auth flow

* refactor: theme data

* revert

* Update qr_widget.dart

* fix: update with new themes

* minor fixes

* feat: put redemption flow under a feature flag

* feat: implement simulated purchasing flow in debug mode

* feat: support LTC and MWEB payments

* Update savings_page.dart

* fix: UI fixes

* add Cake Pay transaction sent bottom sheet

* localization

* Update cake_pay_buy_card_page.dart

* addressing review comments

* fix marge conflicts
This commit is contained in:
Serhii
2025-07-11 23:56:35 +03:00
committed by GitHub
parent 203aff83f2
commit ef84db5874
96 changed files with 3907 additions and 2638 deletions
+1
View File
@@ -3,6 +3,7 @@ import 'dart:io';
class FeatureFlag {
static const bool isCakePayEnabled = false;
static const bool isCakePayRedemptionFlowEnabled = false;
static const bool isExolixEnabled = true;
static const bool isBackgroundSyncEnabled = true;
static final bool isInAppTorEnabled = (Platform.isAndroid);
+55 -63
View File
@@ -3,89 +3,81 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class ImageUtil {
static Widget getImageFromPath({required String imagePath, double? height, double? width}) {
static Widget getImageFromPath({
required String imagePath,
double? height,
double? width,
Color? svgImageColor,
BoxFit? fit,
double? borderRadius,
}) {
bool isNetworkImage = imagePath.startsWith('http') || imagePath.startsWith('https');
if (CakeTor.instance.enabled && isNetworkImage) {
imagePath = "assets/images/tor_logo.svg";
isNetworkImage = false;
}
final bool isSvg = imagePath.endsWith('.svg');
final double _height = height ?? 35;
final double _width = width ?? 35;
final isSvg = imagePath.endsWith('.svg');
final bool ignoreSize = fit != null;
final double? _height = ignoreSize ? null : (height ?? 35);
final double? _width = ignoreSize ? null : (width ?? 35);
Widget img;
if (isNetworkImage) {
return isSvg
? SvgPicture.network(
img = isSvg
? SvgPicture.network(imagePath,
key: ValueKey(imagePath),
imagePath,
height: _height,
width: _width,
placeholderBuilder: (BuildContext context) => Container(
height: _height,
width: _width,
child: Center(
child: CircularProgressIndicator(),
),
),
errorBuilder: (_, __, ___) {
return Container(
height: _height,
width: _width,
child: Center(
child: Icon(Icons.error_outline, color: Colors.grey),
),
);
},
)
: Image.network(
fit: fit ?? BoxFit.contain,
placeholderBuilder: (_) => _placeholder(_height, _width),
errorBuilder: (_, __, ___) => _errorPlaceholder(_height, _width))
: Image.network(imagePath,
key: ValueKey(imagePath),
imagePath,
height: _height,
width: _width,
loadingBuilder:
(BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
}
return Container(
height: _height,
width: _width,
child: Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: null,
),
),
);
},
errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
return Container(
height: _height,
width: _width,
child: Center(
child: Icon(Icons.error_outline, color: Colors.grey),
),
);
},
);
fit: fit,
loadingBuilder: (_, child, progress) =>
progress == null ? child : _placeholder(_height, _width),
errorBuilder: (_, __, ___) => _errorPlaceholder(_height, _width));
} else {
return isSvg
? SvgPicture.asset(
imagePath,
img = isSvg
? SvgPicture.asset(imagePath,
key: ValueKey(imagePath),
height: _height,
width: _width,
placeholderBuilder: (_) => Icon(Icons.error),
errorBuilder: (_, __, ___) => Icon(Icons.error),
key: ValueKey(imagePath),
)
fit: fit ?? BoxFit.contain,
colorFilter:
svgImageColor != null ? ColorFilter.mode(svgImageColor, BlendMode.srcIn) : null,
placeholderBuilder: (_) => _placeholder(_height, _width),
errorBuilder: (_, __, ___) => _errorPlaceholder(_height, _width))
: Image.asset(
imagePath,
key: ValueKey(imagePath),
height: _height,
width: _width,
errorBuilder: (_, __, ___) => Icon(Icons.error),
key: ValueKey(imagePath),
fit: fit,
errorBuilder: (_, __, ___) => _errorPlaceholder(_height, _width),
);
}
if (borderRadius != null && borderRadius > 0) {
img = ClipRRect(
borderRadius: BorderRadius.circular(borderRadius),
child: img,
);
}
return img;
}
static Widget _placeholder(double? h, double? w) => (h != null || w != null)
? SizedBox(height: h, width: w, child: const Center(child: CircularProgressIndicator()))
: const Center(child: CircularProgressIndicator());
static Widget _errorPlaceholder(double? h, double? w) => (h != null || w != null)
? SizedBox(
height: h,
width: w,
child: const Center(child: Icon(Icons.error_outline, color: Colors.grey)))
: const Center(child: Icon(Icons.error_outline, color: Colors.grey));
}