Merge branch 'main' of https://github.com/cake-tech/cake_wallet into linux/password-direct-input

 Conflicts:
	cw_core/lib/wallet_base.dart
	lib/core/auth_service.dart
	lib/di.dart
	lib/main.dart
	lib/router.dart
	lib/routes.dart
	lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
	lib/src/screens/restore/restore_wallet_from_seed_page.dart
	lib/src/screens/settings/security_backup_page.dart
	lib/src/screens/wallet_list/wallet_list_page.dart
	lib/store/settings_store.dart
	lib/view_model/wallet_creation_vm.dart
	macos/Podfile.lock
	pubspec_base.yaml
	res/values/strings_bg.arb
	res/values/strings_en.arb
	res/values/strings_id.arb
	res/values/strings_my.arb
	res/values/strings_nl.arb
	res/values/strings_pt.arb
	res/values/strings_ru.arb
	res/values/strings_th.arb
	res/values/strings_tr.arb
	res/values/strings_uk.arb
	res/values/strings_ur.arb
	res/values/strings_zh.arb
This commit is contained in:
OmarHatem 2023-05-26 15:09:55 +03:00
commit 53d3db5340
280 changed files with 10900 additions and 3845 deletions

View file

@ -5,9 +5,10 @@
## Links
* Website: https://cakewallet.com
* App Store: https://cakewallet.com/ios
* App Store (iOS / MacOS): https://cakewallet.com/ios
* Google Play: https://cakewallet.com/gp
* APK: https://github.com/cake-tech/cake_wallet/releases
* Linux: https://github.com/cake-tech/cake_wallet/releases
## Features
@ -15,18 +16,22 @@
* Completely noncustodial. *Your keys, your coins.*
* Built-in exchange for dozens of pairs
* Buy cryptocurrency with credit/debit/bank
* Easily pay cryptocurrency invoices with fixed rate exchanges
* Buy cryptocurrency (BTC/LTC/XMR) with credit/debit/bank
* Sell cryptocurrency by bank transfer
* Purchase gift cards at a discount using only an email with [Cake Pay](https://cakepay.com), available in-app
* Scan QR codes for easy cryptocurrency transfers
* Create several wallets
* Select your own custom nodes/servers
* Address book
* Backup to external location or iCloud
* Send to OpenAlias, Unstoppable Domains, Yats, and FIO Crypto Handles
* Set custom fee levels
* Set desired network fee level
* Store local transaction notes
* Extremely simple user experience
* Convenient exchange and sending templates for recurring payments
* Create donation links and invoices in the receive screen
* Robust privacy settings (eg: Tor-only connections)
### Monero Specific Features
@ -34,13 +39,13 @@
* Full support for Monero subaddresses and accounts
* Specify restore height for faster syncing
* Specify multiple recipients for batch sending
* Optionally set Monero nodes as trusted for faster syncing
### Bitcoin Specific Features
* Bitcoin coin control (specify specific outputs to spend)
* Automatically generate new addresses
* Specify multiple recipients for batch sending
* Buy BTC with over a dozen fiat currencies
* Sell BTC for USD
### Litecoin Specific Features
@ -48,7 +53,6 @@
* Litecoin coin control (specify specific outputs to spend)
* Automatically generate new addresses
* Specify multiple recipients for batch sending
* Buy LTC with over a dozen fiat currencies
### Haven Specific Features
@ -63,7 +67,7 @@
## Links
* Website: https://monero.com
* App Store: https://apps.apple.com/app/id1601990386
* App Store (iOS): https://apps.apple.com/app/id1601990386
* Google Play: https://play.google.com/store/apps/details?id=com.monero.app
* APK: https://github.com/cake-tech/cake_wallet/releases
@ -71,6 +75,8 @@
We have 24/7 free support. Please contact support@cakewallet.com
We have excellent user guides, which are also open-source and open for contributions: https://guides.cakewallet.com
# Build Instructions
More instructions to follow
@ -108,6 +114,8 @@ Edit the applicable `strings_XX.arb` file in `res/values/` and open a pull reque
- Bulgarian
- Czech
- Indonesian
- Hausa
- Yoruba
## Add a new language
@ -136,3 +144,7 @@ The only parts to be translated, if needed, are the values m and s after the var
3. Add the raw mapping underneath in `lib/entities/fiat_currency.dart` following the same format as the others.
4. Add a flag of the issuing country or organization to `assets/images/flags/XXXX.png`, replacing XXXX with the ISO 3166-1 alpha-3 code used above (eg: `usa.png`, `eur.png`). Do not add this if the flag with the same name already exists. The image must be 42x26 pixels with a 3 pixels of transparent margin on all 4 sides.
---
Copyright (C) 2018-2023 Cake Labs LLC

View file

@ -46,8 +46,14 @@
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="bitcoin" />
<data android:scheme="bitcoin-wallet" />
<data android:scheme="bitcoin_wallet" />
<data android:scheme="monero" />
<data android:scheme="monero-wallet" />
<data android:scheme="monero_wallet" />
<data android:scheme="litecoin" />
<data android:scheme="litecoin-wallet" />
<data android:scheme="litecoin_wallet" />
</intent-filter>
</activity>
<meta-data

View file

@ -24,6 +24,7 @@ import java.security.SecureRandom;
public class MainActivity extends FlutterFragmentActivity {
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
boolean isAppSecure = false;
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
@ -56,6 +57,14 @@ public class MainActivity extends FlutterFragmentActivity {
handler.post(() -> result.success(""));
}
break;
case "setIsAppSecure":
isAppSecure = call.argument("isAppSecure");
if (isAppSecure) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
break;
default:
handler.post(() -> result.notImplemented());
}
@ -80,10 +89,4 @@ public class MainActivity extends FlutterFragmentActivity {
}
});
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
}

View file

@ -23,6 +23,7 @@ import java.security.SecureRandom;
public class MainActivity extends FlutterFragmentActivity {
final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24;
boolean isAppSecure = false;
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
@ -48,13 +49,21 @@ public class MainActivity extends FlutterFragmentActivity {
handler.post(() -> result.success(bytes));
break;
case "getUnstoppableDomainAddress":
int version = Build.VERSION.SDK_INT;
int version = Build.VERSION.SDK_INT;
if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) {
getUnstoppableDomainAddress(call, result);
} else {
handler.post(() -> result.success(""));
}
break;
case "setIsAppSecure":
isAppSecure = call.argument("isAppSecure");
if (isAppSecure) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
break;
default:
handler.post(() -> result.notImplemented());
}

BIN
assets/images/flags/hau.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

View file

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,3 @@
Reliability fixes for PIN login, transaction appearance, keyboard inputs, and QR codes
Show amount received by each Monero account in account overview
Other bugfixes

View file

@ -0,0 +1,3 @@
Reliability fixes for PIN login, transaction appearance, keyboard inputs, and QR codes
Show amount received by each Monero account in account overview
Other bugfixes

View file

@ -88,7 +88,7 @@ class ElectrumClient {
unterminatedString = '';
}
} on TypeError catch (e) {
if (!e.toString().contains('Map<String, Object>') || !e.toString().contains('Map<String, dynamic>')) {
if (!e.toString().contains('Map<String, Object>') && !e.toString().contains('Map<String, dynamic>')) {
return;
}
@ -410,7 +410,7 @@ class ElectrumClient {
switch (method) {
case 'blockchain.scripthash.subscribe':
final params = request['params'] as List<dynamic>;
final scripthash = params.first as String;
final scripthash = params.first as String?;
final id = 'blockchain.scripthash.subscribe:$scripthash';
_tasks[id]?.subject?.add(params.last);
@ -430,15 +430,17 @@ class ElectrumClient {
void _handleResponse(Map<String, dynamic> response) {
final method = response['method'];
final id = response['id'] as String;
final id = response['id'] as String?;
final result = response['result'];
if (method is String) {
_methodHandler(method: method, request: response);
return;
}
_finish(id, result);
if (id != null){
_finish(id, result);
}
}
}

View file

@ -4,7 +4,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_core/balance.dart';
class ElectrumBalance extends Balance {
const ElectrumBalance({required this.confirmed, required this.unconfirmed})
const ElectrumBalance({required this.confirmed, required this.unconfirmed, required this.frozen})
: super(confirmed, unconfirmed);
static ElectrumBalance? fromJSON(String? jsonSource) {
@ -16,20 +16,25 @@ class ElectrumBalance extends Balance {
return ElectrumBalance(
confirmed: decoded['confirmed'] as int? ?? 0,
unconfirmed: decoded['unconfirmed'] as int? ?? 0);
unconfirmed: decoded['unconfirmed'] as int? ?? 0,
frozen: decoded['frozen'] as int? ?? 0);
}
final int confirmed;
final int unconfirmed;
final int frozen;
@override
String get formattedAvailableBalance =>
bitcoinAmountToString(amount: confirmed);
String get formattedAvailableBalance => bitcoinAmountToString(amount: confirmed - frozen);
@override
String get formattedAdditionalBalance =>
bitcoinAmountToString(amount: unconfirmed);
String get formattedAdditionalBalance => bitcoinAmountToString(amount: unconfirmed);
String get formattedFrozenBalance {
final frozenFormatted = bitcoinAmountToString(amount: frozen);
return frozenFormatted == '0.0' ? '' : frozenFormatted;
}
String toJSON() =>
json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed});
json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed, 'frozen': frozen});
}

View file

@ -136,7 +136,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
return ElectrumTransactionInfo(type,
id: bundle.originalTransaction.getId(),
height: height,
isPending: false,
isPending: bundle.confirmations == 0,
fee: fee,
direction: direction,
amount: amount,

View file

@ -64,7 +64,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
_scripthashesUpdateSubject = {},
balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of(
currency != null
? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)}
? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0,
frozen: 0)}
: {}),
this.unspentCoinsInfo = unspentCoinsInfo,
super(walletInfo) {
@ -141,8 +142,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
await walletAddresses.discoverAddresses();
await updateTransactions();
_subscribeForUpdates();
await _updateBalance();
await updateUnspent();
await updateBalance();
_feeRates = await electrumClient.feeRates();
Timer.periodic(const Duration(minutes: 1),
@ -351,7 +352,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
electrumClient: electrumClient, amount: amount, fee: fee)
..addListener((transaction) async {
transactionHistory.addOne(transaction);
await _updateBalance();
await updateBalance();
});
}
@ -505,7 +506,10 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
hash: coin.hash,
isFrozen: coin.isFrozen,
isSending: coin.isSending,
noteRaw: coin.note
noteRaw: coin.note,
address: coin.address.address,
value: coin.value,
vout: coin.vout,
);
await unspentCoinsInfo.add(newInfo);
@ -541,8 +545,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
final transactionHex = verboseTransaction['hex'] as String;
final original = bitcoin.Transaction.fromHex(transactionHex);
final ins = <bitcoin.Transaction>[];
final time = verboseTransaction['time'] as int;
final confirmations = verboseTransaction['confirmations'] as int ?? 0;
final time = verboseTransaction['time'] as int?;
final confirmations = verboseTransaction['confirmations'] as int? ?? 0;
for (final vin in original.ins) {
final id = HEX.encode(vin.hash!.reversed.toList());
@ -642,8 +646,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
_scripthashesUpdateSubject[sh] = electrumClient.scripthashUpdate(sh);
_scripthashesUpdateSubject[sh]?.listen((event) async {
try {
await _updateBalance();
await updateUnspent();
await updateBalance();
await updateTransactions();
} catch (e) {
print(e.toString());
@ -661,7 +665,17 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
final sh = scriptHash(addressRecord.address, networkType: networkType);
final balanceFuture = electrumClient.getBalance(sh);
balanceFutures.add(balanceFuture);
}
}
var totalFrozen = 0;
unspentCoinsInfo.values.forEach((info) {
unspentCoins.forEach((element) {
if (element.hash == info.hash && info.isFrozen && element.address.address == info.address
&& element.value == info.value) {
totalFrozen += element.value;
}
});
});
final balances = await Future.wait(balanceFutures);
var totalConfirmed = 0;
@ -680,10 +694,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
}
}
return ElectrumBalance(confirmed: totalConfirmed, unconfirmed: totalUnconfirmed);
return ElectrumBalance(confirmed: totalConfirmed, unconfirmed: totalUnconfirmed,
frozen: totalFrozen);
}
Future<void> _updateBalance() async {
Future<void> updateBalance() async {
balance[currency] = await _fetchBalances();
await save();
}

View file

@ -37,7 +37,7 @@ class ElectrumWallletSnapshot {
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
.toList();
final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
ElectrumBalance(confirmed: 0, unconfirmed: 0);
ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
var regularAddressIndex = 0;
var changeAddressIndex = 0;

View file

@ -1,10 +1,12 @@
class Account {
Account({required this.id, required this.label});
Account({required this.id, required this.label, this.balance});
Account.fromMap(Map<String, Object> map)
: this.id = map['id'] == null ? 0 : int.parse(map['id'] as String),
this.label = (map['label'] ?? '') as String;
this.label = (map['label'] ?? '') as String,
this.balance = (map['balance'] ?? '0.00') as String;
final int id;
final String label;
final String? balance;
}

View file

@ -8,4 +8,6 @@ abstract class Balance {
String get formattedAvailableBalance;
String get formattedAdditionalBalance;
String get formattedFrozenBalance => '';
}

View file

@ -66,6 +66,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.scrt,
CryptoCurrency.uni,
CryptoCurrency.stx,
CryptoCurrency.btcln,
];
static const havenCurrencies = [
@ -150,6 +151,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
static const scrt = CryptoCurrency(title: 'SCRT', fullName: 'Secret Network', raw: 59, name: 'scrt', iconPath: 'assets/images/scrt_icon.png');
static const uni = CryptoCurrency(title: 'UNI', tag: 'ETH', fullName: 'Uniswap', raw: 60, name: 'uni', iconPath: 'assets/images/uni_icon.png');
static const stx = CryptoCurrency(title: 'STX', fullName: 'Stacks', raw: 61, name: 'stx', iconPath: 'assets/images/stx_icon.png');
static const btcln = CryptoCurrency(title: 'BTC', tag: 'LN', fullName: 'Bitcoin Lightning Network', raw: 62, name: 'btcln', iconPath: 'assets/images/btc.png');
static final Map<int, CryptoCurrency> _rawCurrencyMap =
[...all, ...havenCurrencies].fold<Map<int, CryptoCurrency>>(<int, CryptoCurrency>{}, (acc, item) {

View file

@ -122,6 +122,8 @@ int getMoneroHeigthByDate({required DateTime date}) {
}
const havenDates = {
"2023-05": 1352995,
"2023-04": 1331460,
"2023-03": 1309180,
"2023-01": 1266810,
"2022-12": 1244510,

View file

@ -0,0 +1,7 @@
import 'package:flutter/services.dart';
const utils = const MethodChannel('com.cake_wallet/native_utils');
void setIsAppSecureNative(bool isAppSecure) {
utils.invokeMethod<Uint8List>('setIsAppSecure', {'isAppSecure': isAppSecure});
}

View file

@ -9,7 +9,10 @@ class UnspentCoinsInfo extends HiveObject {
required this.hash,
required this.isFrozen,
required this.isSending,
required this.noteRaw});
required this.noteRaw,
required this.address,
required this.vout,
required this.value});
static const typeId = 9;
static const boxName = 'Unspent';
@ -30,6 +33,15 @@ class UnspentCoinsInfo extends HiveObject {
@HiveField(4)
String? noteRaw;
@HiveField(5, defaultValue: '')
String address;
@HiveField(6, defaultValue: 0)
int value;
@HiveField(7, defaultValue: 0)
int vout;
String get note => noteRaw ?? '';
set note(String value) => noteRaw = value;

View file

@ -73,4 +73,6 @@ abstract class WalletBase<
Future<void> changePassword(String password);
String get password;
Future<void>? updateBalance();
}

View file

@ -104,6 +104,9 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
(_) async => await save());
}
@override
Future<void>? updateBalance() => null;
@override
void close() {
_listener?.stop();

View file

@ -115,10 +115,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "13a6ccf6a459a125b3fcdb6ec73bd5ff90822e071207c663bfd1f70062d51d18"
sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "2.0.1"
file:
dependency: transitive
description:
@ -277,10 +277,10 @@ packages:
dependency: transitive
description:
name: path_provider_windows
sha256: a34ecd7fb548f8e57321fd8e50d865d266941b54e6c3b7758cf8f37c24116905
sha256: f53720498d5a543f9607db4b0e997c4b5438884de25b0f73098cc2671a51b130
url: "https://pub.dev"
source: hosted
version: "2.0.7"
version: "2.1.5"
platform:
dependency: transitive
description:
@ -386,10 +386,10 @@ packages:
dependency: transitive
description:
name: win32
sha256: c0e3a4f7be7dae51d8f152230b86627e3397c1ba8c3fa58e63d44a9f3edc9cef
sha256: a6f0236dbda0f63aa9a25ad1ff9a9d8a4eaaa5012da0dc59d21afdb1dc361ca4
url: "https://pub.dev"
source: hosted
version: "2.6.1"
version: "3.1.4"
xdg_directories:
dependency: transitive
description:
@ -399,5 +399,5 @@ packages:
source: hosted
version: "0.2.0+3"
sdks:
dart: ">=2.18.1 <3.0.0"
dart: ">=2.18.1 <4.0.0"
flutter: ">=3.0.0"

View file

@ -1,6 +1,8 @@
import 'package:cw_core/monero_amount_format.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_core/account.dart';
import 'package:cw_monero/api/account_list.dart' as account_list;
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
part 'monero_account_list.g.dart';
@ -41,12 +43,16 @@ abstract class MoneroAccountListBase with Store {
}
}
List<Account> getAll() => account_list
.getAllAccount()
.map((accountRow) => Account(
id: accountRow.getId(),
label: accountRow.getLabel()))
.toList();
List<Account> getAll() => account_list.getAllAccount().map((accountRow) {
final accountIndex = accountRow.getId();
final balance = monero_wallet.getFullBalance(accountIndex: accountIndex);
return Account(
id: accountRow.getId(),
label: accountRow.getLabel(),
balance: moneroAmountToString(amount: balance),
);
}).toList();
Future<void> addAccount({required String label}) async {
await account_list.addAccount(label: label);
@ -54,8 +60,7 @@ abstract class MoneroAccountListBase with Store {
}
Future<void> setLabelAccount({required int accountIndex, required String label}) async {
await account_list.setLabelForAccount(
accountIndex: accountIndex, label: label);
await account_list.setLabelForAccount(accountIndex: accountIndex, label: label);
update();
}

View file

@ -125,6 +125,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
Duration(seconds: _autoSaveInterval),
(_) async => await save());
}
@override
Future<void>? updateBalance() => null;
@override
void close() {

View file

@ -113,7 +113,9 @@ PODS:
- OrderedSet (~> 5.0)
- flutter_mailer (0.0.1):
- Flutter
- flutter_secure_storage (3.3.1):
- flutter_secure_storage (6.0.0):
- Flutter
- in_app_review (0.2.0):
- Flutter
- local_auth_ios (0.0.1):
- Flutter
@ -165,6 +167,7 @@ DEPENDENCIES:
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- flutter_mailer (from `.symlinks/plugins/flutter_mailer/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
@ -220,6 +223,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_mailer/ios"
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
in_app_review:
:path: ".symlinks/plugins/in_app_review/ios"
local_auth_ios:
:path: ".symlinks/plugins/local_auth_ios/ios"
package_info:
@ -259,18 +264,19 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
SwiftProtobuf: afced68785854575756db965e9da52bbf3dc45e7
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a

View file

@ -15,6 +15,8 @@ import UnstoppableDomainsResolution
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
makeSecure()
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let legacyMigrationChannel = FlutterMethodChannel(
@ -96,21 +98,39 @@ import UnstoppableDomainsResolution
result(address)
}
case "setIsAppSecure":
guard let args = call.arguments as? Dictionary<String, Bool>,
let isAppSecure = args["isAppSecure"] else {
result(nil)
return
}
if isAppSecure {
self?.textField.isSecureTextEntry = true
} else {
self?.textField.isSecureTextEntry = false
}
result(nil)
default:
result(FlutterMethodNotImplemented)
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private var textField = UITextField()
private func makeSecure() {
if (!self.window.subviews.contains(textField)) {
self.window.addSubview(textField)
textField.centerYAnchor.constraint(equalTo: self.window.centerYAnchor).isActive = true
textField.centerXAnchor.constraint(equalTo: self.window.centerXAnchor).isActive = true
self.window.layer.superlayer?.addSublayer(textField.layer)
textField.layer.sublayers?.first?.addSublayer(self.window.layer)
}
}
override func applicationWillResignActive(_: UIApplication ) {
self.window?.isHidden = true;
}
override func applicationDidBecomeActive(_: UIApplication) {
self.window?.isHidden = false;
}
}

View file

@ -42,6 +42,16 @@
<string>bitcoin</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>bitcoin-wallet</string>
<key>CFBundleURLSchemes</key>
<array>
<string>bitcoin-wallet</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
@ -52,6 +62,16 @@
<string>monero</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>monero-wallet</string>
<key>CFBundleURLSchemes</key>
<array>
<string>monero-wallet</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
@ -62,6 +82,16 @@
<string>litecoin</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLName</key>
<string>litecoin-wallet</string>
<key>CFBundleURLSchemes</key>
<array>
<string>litecoin-wallet</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>

View file

@ -1,6 +1,7 @@
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/wallet_base.dart';
class OnRamperBuyProvider {
@ -13,7 +14,16 @@ class OnRamperBuyProvider {
static const _baseUrl = 'buy.onramper.com';
static String get _apiKey => secrets.onramperApiKey;
String get _apiKey => secrets.onramperApiKey;
String get _normalizeCryptoCurrency {
switch (_wallet.currency) {
case CryptoCurrency.ltc:
return "LTC_LITECOIN";
default:
return _wallet.currency.title;
}
}
Uri requestUrl() {
String primaryColor,
@ -53,7 +63,7 @@ class OnRamperBuyProvider {
return Uri.https(_baseUrl, '', <String, dynamic>{
'apiKey': _apiKey,
'defaultCrypto': _wallet.currency.title,
'defaultCrypto': _normalizeCryptoCurrency,
'defaultFiat': _settingsStore.fiatCurrency.title,
'wallets': '${_wallet.currency.title}:${_wallet.walletAddresses.address}',
'supportSell': "false",

View file

@ -1,4 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/validator.dart';
import 'package:cw_core/crypto_currency.dart';
@ -7,6 +7,9 @@ class AddressValidator extends TextValidator {
AddressValidator({required CryptoCurrency type})
: super(
errorMessage: S.current.error_text_address,
useAdditionalValidation: type == CryptoCurrency.btc
? bitcoin.Address.validateAddress
: null,
pattern: getPattern(type),
length: getLength(type));
@ -18,8 +21,7 @@ class AddressValidator extends TextValidator {
return '^[0-9a-zA-Z]{59}\$|^[0-9a-zA-Z]{92}\$|^[0-9a-zA-Z]{104}\$'
'|^[0-9a-zA-Z]{105}\$|^addr1[0-9a-zA-Z]{98}\$';
case CryptoCurrency.btc:
return '^1[0-9a-zA-Z]{32}\$|^1[0-9a-zA-Z]{33}\$|^3[0-9a-zA-Z]{32}\$'
'|^3[0-9a-zA-Z]{33}\$|^bc1[0-9a-zA-Z]{39}\$|^bc1[0-9a-zA-Z]{59}\$';
return '^3[0-9a-zA-Z]{32}\$|^3[0-9a-zA-Z]{33}\$|^bc1[0-9a-zA-Z]{59}\$';
case CryptoCurrency.nano:
return '[0-9a-zA-Z_]';
case CryptoCurrency.usdc:
@ -59,11 +61,12 @@ class AddressValidator extends TextValidator {
case CryptoCurrency.dai:
case CryptoCurrency.dash:
case CryptoCurrency.eos:
case CryptoCurrency.ltc:
case CryptoCurrency.bch:
case CryptoCurrency.bnb:
return '[0-9a-zA-Z]';
case CryptoCurrency.hbar:
case CryptoCurrency.ltc:
return '^(?!(ltc|LTC)1)[0-9a-zA-Z]*\$|(^LTC1[A-Z0-9]*\$)|(^ltc1[a-z0-9]*\$)';
case CryptoCurrency.hbar:
return '[0-9a-zA-Z.]';
case CryptoCurrency.zaddr:
return '^zs[0-9a-zA-Z]{75}';
@ -85,6 +88,8 @@ class AddressValidator extends TextValidator {
return 'R[0-9a-zA-Z]{33}';
case CryptoCurrency.pivx:
return 'D([1-9a-km-zA-HJ-NP-Z]){33}';
case CryptoCurrency.btcln:
return '^(lnbc|LNBC)([0-9]{1,}[a-zA-Z0-9]+)';
default:
return '[0-9a-zA-Z]';
}
@ -115,7 +120,7 @@ class AddressValidator extends TextValidator {
case CryptoCurrency.eth:
return [42];
case CryptoCurrency.ltc:
return [34, 43];
return [34, 43, 63];
case CryptoCurrency.nano:
return [64, 65];
case CryptoCurrency.sc:
@ -163,9 +168,9 @@ class AddressValidator extends TextValidator {
return [34];
case CryptoCurrency.hbar:
return [4, 5, 6, 7, 8, 9, 10, 11];
case CryptoCurrency.xvg:
case CryptoCurrency.xvg:
return [34];
case CryptoCurrency.zen:
case CryptoCurrency.zen:
return [35];
case CryptoCurrency.zaddr:
return null;
@ -194,6 +199,8 @@ class AddressValidator extends TextValidator {
return [45];
case CryptoCurrency.near:
return [64];
case CryptoCurrency.btcln:
return null;
default:
return [];
}

View file

@ -1,19 +1,48 @@
import 'package:cake_wallet/core/validator.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/currency.dart';
class AmountValidator extends TextValidator {
AmountValidator({required CryptoCurrency currency, bool isAutovalidate = false}) {
AmountValidator({
required CryptoCurrency currency,
bool isAutovalidate = false,
String? minValue,
String? maxValue,
}) {
symbolsAmountValidator =
SymbolsAmountValidator(isAutovalidate: isAutovalidate);
decimalAmountValidator = DecimalAmountValidator(currency: currency,isAutovalidate: isAutovalidate);
amountMinValidator = AmountMinValidator(
minValue: minValue,
isAutovalidate: isAutovalidate,
);
amountMaxValidator = AmountMaxValidator(
maxValue: maxValue,
isAutovalidate: isAutovalidate,
);
}
late final AmountMinValidator amountMinValidator;
late final AmountMaxValidator amountMaxValidator;
late final SymbolsAmountValidator symbolsAmountValidator;
late final DecimalAmountValidator decimalAmountValidator;
String? call(String? value) => symbolsAmountValidator(value) ?? decimalAmountValidator(value);
String? call(String? value) {
//* Validate for Text(length, symbols, decimals etc)
final textValidation = symbolsAmountValidator(value) ?? decimalAmountValidator(value);
//* Validate for Comparison(Value greater than min and less than )
final comparisonValidation = amountMinValidator(value) ?? amountMaxValidator(value);
return textValidation ?? comparisonValidation;
}
}
class SymbolsAmountValidator extends TextValidator {
@ -29,7 +58,7 @@ class SymbolsAmountValidator extends TextValidator {
}
class DecimalAmountValidator extends TextValidator {
DecimalAmountValidator({required CryptoCurrency currency, required bool isAutovalidate })
DecimalAmountValidator({required Currency currency, required bool isAutovalidate })
: super(
errorMessage: S.current.decimal_places_error,
pattern: _pattern(currency),
@ -37,7 +66,7 @@ class DecimalAmountValidator extends TextValidator {
minLength: 0,
maxLength: 0);
static String _pattern(CryptoCurrency currency) {
static String _pattern(Currency currency) {
switch (currency) {
case CryptoCurrency.xmr:
return '^([0-9]+([.\,][0-9]{1,12})?|[.\,][0-9]{1,12})\$';
@ -57,3 +86,71 @@ class AllAmountValidator extends TextValidator {
minLength: 0,
maxLength: 0);
}
class AmountMinValidator extends Validator<String> {
final String? minValue;
final bool isAutovalidate;
AmountMinValidator({
this.minValue,
required this.isAutovalidate,
}) : super(errorMessage: S.current.error_text_input_below_minimum_limit);
@override
bool isValid(String? value) {
if (value == null || value.isEmpty) {
return isAutovalidate ? true : false;
}
if (minValue == null || minValue == "null") {
return true;
}
final valueInDouble = parseToDouble(value);
final minInDouble = parseToDouble(minValue ?? '');
if (valueInDouble == null || minInDouble == null) {
return false;
}
return valueInDouble > minInDouble;
}
double? parseToDouble(String value) {
final data = double.tryParse(value.replaceAll(',', '.'));
return data;
}
}
class AmountMaxValidator extends Validator<String> {
final String? maxValue;
final bool isAutovalidate;
AmountMaxValidator({
this.maxValue,
required this.isAutovalidate,
}) : super(errorMessage: S.current.error_text_input_above_maximum_limit);
@override
bool isValid(String? value) {
if (value == null || value.isEmpty) {
return isAutovalidate ? true : false;
}
if (maxValue == null || maxValue == "null") {
return true;
}
final valueInDouble = parseToDouble(value);
final maxInDouble = parseToDouble(maxValue ?? '');
if (valueInDouble == null || maxInDouble == null) {
return false;
}
return valueInDouble < maxInDouble;
}
double? parseToDouble(String value) {
return double.tryParse(value.replaceAll(',', '.'));
}
}

View file

@ -1,12 +1,17 @@
import 'package:cake_wallet/core/totp_request_details.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cake_wallet/entities/encrypt.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/store/settings_store.dart';
import '../src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
class AuthService with Store {
AuthService({
required this.secureStorage,
@ -14,6 +19,14 @@ class AuthService with Store {
required this.settingsStore,
});
static const List<String> _alwaysAuthenticateRoutes = [
Routes.showKeys,
Routes.backup,
Routes.setupPin,
Routes.setup_2faPage,
Routes.modify2FAPage,
];
final SecureStorage secureStorage;
final SharedPreferences sharedPreferences;
final SettingsStore settingsStore;
@ -66,4 +79,60 @@ class AuthService with Store {
return timeDifference.inMinutes;
}
Future<void> authenticateAction(BuildContext context,
{Function(bool)? onAuthSuccess, String? route, Object? arguments}) async {
assert(route != null || onAuthSuccess != null,
'Either route or onAuthSuccess param must be passed.');
if (!requireAuth() && !_alwaysAuthenticateRoutes.contains(route)) {
if (onAuthSuccess != null) {
onAuthSuccess(true);
} else {
Navigator.of(context).pushNamed(
route ?? '',
arguments: arguments,
);
}
return;
}
Navigator.of(context).pushNamed(Routes.auth,
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
if (!isAuthenticatedSuccessfully) {
onAuthSuccess?.call(false);
return;
} else {
if (settingsStore.useTOTP2FA) {
auth.close(
route: Routes.totpAuthCodePage,
arguments: TotpAuthArgumentsModel(
isForSetup: !settingsStore.useTOTP2FA,
onTotpAuthenticationFinished:
(bool isAuthenticatedSuccessfully, TotpAuthCodePageState totpAuth) async {
if (!isAuthenticatedSuccessfully) {
onAuthSuccess?.call(false);
return;
}
if (onAuthSuccess != null) {
totpAuth.close().then((value) => onAuthSuccess.call(true));
} else {
totpAuth.close(route: route, arguments: arguments);
}
},
),
);
} else {
if (onAuthSuccess != null) {
auth.close().then((value) => onAuthSuccess.call(true));
} else {
auth.close(route: route, arguments: arguments);
}
}
}
});
}
}

View file

@ -210,6 +210,9 @@ class BackupService {
final currentBalanceDisplayMode = data[PreferencesKey.currentBalanceDisplayModeKey] as int?;
final currentFiatCurrency = data[PreferencesKey.currentFiatCurrencyKey] as String?;
final shouldSaveRecipientAddress = data[PreferencesKey.shouldSaveRecipientAddressKey] as bool?;
final isAppSecure = data[PreferencesKey.isAppSecureKey] as bool?;
final disableBuy = data[PreferencesKey.disableBuyKey] as bool?;
final disableSell = data[PreferencesKey.disableSellKey] as bool?;
final currentTransactionPriorityKeyLegacy = data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?;
final allowBiometricalAuthentication = data[PreferencesKey.allowBiometricalAuthenticationKey] as bool?;
final currentBitcoinElectrumSererId = data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int?;
@ -246,6 +249,21 @@ class BackupService {
PreferencesKey.shouldSaveRecipientAddressKey,
shouldSaveRecipientAddress);
if (isAppSecure != null)
await _sharedPreferences.setBool(
PreferencesKey.isAppSecureKey,
isAppSecure);
if (disableBuy != null)
await _sharedPreferences.setBool(
PreferencesKey.disableBuyKey,
disableBuy);
if (disableSell != null)
await _sharedPreferences.setBool(
PreferencesKey.disableSellKey,
disableSell);
if (currentTransactionPriorityKeyLegacy != null)
await _sharedPreferences.setInt(
PreferencesKey.currentTransactionPriorityKeyLegacy,
@ -416,6 +434,10 @@ class BackupService {
_sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey),
PreferencesKey.shouldSaveRecipientAddressKey: _sharedPreferences
.getBool(PreferencesKey.shouldSaveRecipientAddressKey),
PreferencesKey.disableBuyKey: _sharedPreferences
.getBool(PreferencesKey.disableBuyKey),
PreferencesKey.disableSellKey: _sharedPreferences
.getBool(PreferencesKey.disableSellKey),
PreferencesKey.isDarkThemeLegacy:
_sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy),
PreferencesKey.currentPinLength:

View file

@ -0,0 +1,13 @@
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
class TotpAuthArgumentsModel {
final bool? isForSetup;
final bool? isClosable;
final OnTotpAuthenticationFinished? onTotpAuthenticationFinished;
TotpAuthArgumentsModel({
this.isForSetup,
this.isClosable,
this.onTotpAuthenticationFinished,
});
}

View file

@ -1,24 +1,26 @@
import 'package:flutter/foundation.dart';
abstract class Validator<T> {
Validator({required this.errorMessage});
Validator({required this.errorMessage, this.useAdditionalValidation});
final String errorMessage;
final bool Function(T)? useAdditionalValidation;
bool isValid(T? value);
String? call(T? value) => !isValid(value) ? errorMessage : null;
String? call(T? value) => !isValid(value) ? errorMessage : null;
}
class TextValidator extends Validator<String> {
TextValidator(
{this.minLength,
this.maxLength,
this.pattern,
String errorMessage = '',
this.length,
this.isAutovalidate = false})
: super(errorMessage: errorMessage);
TextValidator({
bool Function(String)? useAdditionalValidation,
this.minLength,
this.maxLength,
this.pattern,
String errorMessage = '',
this.length,
this.isAutovalidate = false,
}) : super(
errorMessage: errorMessage,
useAdditionalValidation: useAdditionalValidation);
final int? minLength;
final int? maxLength;
@ -32,11 +34,26 @@ class TextValidator extends Validator<String> {
return isAutovalidate ? true : false;
}
return value.length > (minLength ?? 0) &&
(length?.contains(value.length) ?? true) &&
((maxLength ?? 0) > 0 ? (value.length <= maxLength!) : true) &&
(pattern != null ? match(value) : true);
final greaterThanMinLength = value.length > (minLength ?? 0);
if (!greaterThanMinLength) return false;
final lengthMatched = length?.contains(value.length) ?? true;
if (!lengthMatched) return false;
final lowerThanMaxLength =
(maxLength ?? 0) > 0 ? (value.length <= maxLength!) : true;
if (!lowerThanMaxLength) return false;
if (pattern == null) return true;
final valueMatched = match(value);
final valueValidated = useAdditionalValidation != null
? useAdditionalValidation!(value) || valueMatched
: valueMatched;
return valueValidated;
}
bool match(String value) => pattern != null ? RegExp(pattern!).hasMatch(value) : false;
bool match(String value) =>
pattern != null ? RegExp(pattern!).hasMatch(value) : false;
}

View file

@ -16,6 +16,7 @@ import 'package:cake_wallet/entities/receive_page_option.dart';
import 'package:cake_wallet/ionia/ionia_anypay.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_tip.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
@ -39,6 +40,10 @@ import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.da
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
@ -65,6 +70,8 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart';
import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
@ -200,6 +207,9 @@ import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
import 'package:cake_wallet/core/wallet_loading_service.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart';
import 'package:cake_wallet/entities/qr_view_data.dart';
import 'core/totp_request_details.dart';
final getIt = GetIt.instance;
@ -215,18 +225,18 @@ late Box<Order> _ordersSource;
late Box<UnspentCoinsInfo>? _unspentCoinsInfoSource;
late Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
Future setup(
{required Box<WalletInfo> walletInfoSource,
required Box<Node> nodeSource,
required Box<Contact> contactSource,
required Box<Trade> tradesSource,
required Box<Template> templates,
required Box<ExchangeTemplate> exchangeTemplates,
required Box<TransactionDescription> transactionDescriptionBox,
required Box<Order> ordersSource,
Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource
}) async {
Future setup({
required Box<WalletInfo> walletInfoSource,
required Box<Node> nodeSource,
required Box<Contact> contactSource,
required Box<Trade> tradesSource,
required Box<Template> templates,
required Box<ExchangeTemplate> exchangeTemplates,
required Box<TransactionDescription> transactionDescriptionBox,
required Box<Order> ordersSource,
Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
}) async {
_walletInfoSource = walletInfoSource;
_nodeSource = nodeSource;
_contactSource = contactSource;
@ -239,8 +249,7 @@ Future setup(
_anonpayInvoiceInfoSource = anonpayInvoiceInfoSource;
if (!_isSetupFinished) {
getIt.registerSingletonAsync<SharedPreferences>(
() => SharedPreferences.getInstance());
getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
}
final isBitcoinBuyEnabled = (secrets.wyreSecretKey.isNotEmpty ?? false) &&
@ -270,74 +279,72 @@ Future setup(
walletList: getIt.get<WalletListStore>(),
settingsStore: getIt.get<SettingsStore>(),
nodeListStore: getIt.get<NodeListStore>()));
getIt.registerSingleton<TradesStore>(TradesStore(
tradesSource: _tradesSource, settingsStore: getIt.get<SettingsStore>()));
getIt.registerSingleton<OrdersStore>(OrdersStore(
ordersSource: _ordersSource, settingsStore: getIt.get<SettingsStore>()));
getIt.registerSingleton<TradesStore>(
TradesStore(tradesSource: _tradesSource, settingsStore: getIt.get<SettingsStore>()));
getIt.registerSingleton<OrdersStore>(
OrdersStore(ordersSource: _ordersSource, settingsStore: getIt.get<SettingsStore>()));
getIt.registerSingleton<TradeFilterStore>(TradeFilterStore());
getIt.registerSingleton<TransactionFilterStore>(TransactionFilterStore());
getIt.registerSingleton<FiatConversionStore>(FiatConversionStore());
getIt.registerSingleton<SendTemplateStore>(
SendTemplateStore(templateSource: _templates));
getIt.registerSingleton<SendTemplateStore>(SendTemplateStore(templateSource: _templates));
getIt.registerSingleton<ExchangeTemplateStore>(
ExchangeTemplateStore(templateSource: _exchangeTemplates));
getIt.registerSingleton<YatStore>(YatStore(
appStore: getIt.get<AppStore>(),
secureStorage: getIt.get<SecureStorage>())
..init());
getIt.registerSingleton<AnonpayTransactionsStore>(AnonpayTransactionsStore(
anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
getIt.registerSingleton<YatStore>(
YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>())
..init());
getIt.registerSingleton<AnonpayTransactionsStore>(
AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
final secretStore =
await SecretStoreBase.load(getIt.get<SecureStorage>());
final secretStore = await SecretStoreBase.load(getIt.get<SecureStorage>());
getIt.registerSingleton<SecretStore>(secretStore);
getIt.registerFactory<KeyService>(
() => KeyService(getIt.get<SecureStorage>()));
getIt.registerFactory<KeyService>(() => KeyService(getIt.get<SecureStorage>()));
getIt.registerFactoryParam<WalletCreationService, WalletType, void>(
(type, _) => WalletCreationService(
getIt.registerFactoryParam<WalletCreationService, WalletType, void>((type, _) =>
WalletCreationService(
initialType: type,
keyService: getIt.get<KeyService>(),
sharedPreferences: getIt.get<SharedPreferences>(),
walletInfoSource: _walletInfoSource));
getIt.registerFactory<WalletLoadingService>(
() => WalletLoadingService(
getIt.registerFactory<WalletLoadingService>(() => WalletLoadingService(
getIt.get<SharedPreferences>(),
getIt.get<KeyService>(),
(WalletType type) => getIt.get<WalletService>(param1: type)));
getIt.registerFactoryParam<WalletNewVM, WalletType, void>((type, _) =>
WalletNewVM(getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type));
getIt.registerFactoryParam<WalletNewVM, WalletType, void>((type, _) => WalletNewVM(
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type));
getIt
.registerFactoryParam<WalletRestorationFromSeedVM, List, void>((args, _) {
getIt.registerFactoryParam<WalletRestorationFromSeedVM, List, void>((args, _) {
final type = args.first as WalletType;
final language = args[1] as String;
final mnemonic = args[2] as String;
return WalletRestorationFromSeedVM(getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
return WalletRestorationFromSeedVM(
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type, language: language, seed: mnemonic);
});
getIt
.registerFactoryParam<WalletRestorationFromKeysVM, List, void>((args, _) {
getIt.registerFactoryParam<WalletRestorationFromKeysVM, List, void>((args, _) {
final type = args.first as WalletType;
final language = args[1] as String;
return WalletRestorationFromKeysVM(getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
return WalletRestorationFromKeysVM(
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type, language: language);
});
getIt.registerFactory<WalletAddressListViewModel>(() =>
WalletAddressListViewModel(
appStore: getIt.get<AppStore>(), yatStore: getIt.get<YatStore>()));
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
return WalletRestorationFromQRVM(getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
});
getIt.registerFactory<WalletAddressListViewModel>(() => WalletAddressListViewModel(
appStore: getIt.get<AppStore>(),
yatStore: getIt.get<YatStore>(),
fiatConversionStore: getIt.get<FiatConversionStore>()));
getIt.registerFactory(() => BalanceViewModel(
appStore: getIt.get<AppStore>(),
@ -353,65 +360,109 @@ Future setup(
settingsStore: settingsStore,
yatStore: getIt.get<YatStore>(),
ordersStore: getIt.get<OrdersStore>(),
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>())
);
anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>()));
getIt.registerFactory<AuthService>(() => AuthService(
getIt.registerFactory<AuthService>(
() => AuthService(
secureStorage: getIt.get<SecureStorage>(),
sharedPreferences: getIt.get<SharedPreferences>(),
settingsStore: getIt.get<SettingsStore>(),
),
);
),
);
getIt.registerFactory<AuthViewModel>(() => AuthViewModel(
getIt.get<AuthService>(),
getIt.get<SharedPreferences>(),
getIt.registerFactory<AuthViewModel>(() => AuthViewModel(getIt.get<AuthService>(),
getIt.get<SharedPreferences>(), getIt.get<SettingsStore>(), BiometricAuth()));
getIt.registerFactoryParam<AuthPage, void Function(bool, AuthPageState), bool>(
(onAuthFinished, closable) => AuthPage(getIt.get<AuthViewModel>(),
onAuthenticationFinished: onAuthFinished, closable: closable));
getIt.registerFactory<Setup2FAViewModel>(
() => Setup2FAViewModel(
getIt.get<SettingsStore>(),
BiometricAuth()));
getIt.get<SharedPreferences>(),
getIt.get<AuthService>(),
),
);
getIt.registerFactory<AuthPage>(
() => AuthPage(getIt.get<AuthViewModel>(), onAuthenticationFinished:
(isAuthenticated, AuthPageState authPageState) {
if (!isAuthenticated) {
return;
}
final authStore = getIt.get<AuthenticationStore>();
final appStore = getIt.get<AppStore>();
getIt.registerFactoryParam<TotpAuthCodePage, TotpAuthArgumentsModel, void>(
(totpAuthPageArguments, _) => TotpAuthCodePage(
getIt.get<Setup2FAViewModel>(),
totpArguments: totpAuthPageArguments,
),
);
if (appStore.wallet != null) {
authStore.allowed();
return;
}
getIt.registerFactory<AuthPage>(() {
return AuthPage(getIt.get<AuthViewModel>(),
onAuthenticationFinished: (isAuthenticated, AuthPageState authPageState) {
if (!isAuthenticated) {
return;
} else {
final authStore = getIt.get<AuthenticationStore>();
final appStore = getIt.get<AppStore>();
final useTotp = appStore.settingsStore.useTOTP2FA;
if (useTotp) {
authPageState.close(
route: Routes.totpAuthCodePage,
arguments: TotpAuthArgumentsModel(
isForSetup: false,
isClosable: false,
onTotpAuthenticationFinished: (bool isAuthenticatedSuccessfully,
TotpAuthCodePageState totpAuthPageState) async {
if (!isAuthenticatedSuccessfully) {
return;
}
if (appStore.wallet != null) {
authStore.allowed();
return;
}
authPageState.changeProcessText('Loading the wallet');
totpAuthPageState.changeProcessText('Loading the wallet');
if (loginError != null) {
authPageState
.changeProcessText('ERROR: ${loginError.toString()}');
}
if (loginError != null) {
totpAuthPageState.changeProcessText('ERROR: ${loginError.toString()}');
}
ReactionDisposer? _reaction;
_reaction = reaction((_) => appStore.wallet, (Object? _) {
_reaction?.reaction.dispose();
authStore.allowed();
});
}, closable: false),
instanceName: 'login');
ReactionDisposer? _reaction;
_reaction = reaction((_) => appStore.wallet, (Object? _) {
_reaction?.reaction.dispose();
authStore.allowed();
});
},
),
);
} else {
if (appStore.wallet != null) {
authStore.allowed();
return;
}
getIt
.registerFactoryParam<AuthPage, void Function(bool, AuthPageState), bool>(
(onAuthFinished, closable) => AuthPage(getIt.get<AuthViewModel>(),
onAuthenticationFinished: onAuthFinished,
closable: closable));
authPageState.changeProcessText('Loading the wallet');
getIt.registerFactory(() =>
BalancePage(dashboardViewModel: getIt.get<DashboardViewModel>(), settingsStore: getIt.get<SettingsStore>()));
if (loginError != null) {
authPageState.changeProcessText('ERROR: ${loginError.toString()}');
}
ReactionDisposer? _reaction;
_reaction = reaction((_) => appStore.wallet, (Object? _) {
_reaction?.reaction.dispose();
authStore.allowed();
});
}
}
}, closable: false);
}, instanceName: 'login');
getIt.registerFactory(() => BalancePage(
dashboardViewModel: getIt.get<DashboardViewModel>(),
settingsStore: getIt.get<SettingsStore>()));
getIt.registerFactory<DashboardPage>(() => DashboardPage(
balancePage: getIt.get<BalancePage>(),
dashboardViewModel: getIt.get<DashboardViewModel>(),
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
));
balancePage: getIt.get<BalancePage>(),
dashboardViewModel: getIt.get<DashboardViewModel>(),
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
));
getIt.registerFactory<DesktopSidebarWrapper>(() {
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
return DesktopSidebarWrapper(
@ -423,16 +474,26 @@ Future setup(
});
getIt.registerFactoryParam<DesktopDashboardPage, GlobalKey<NavigatorState>, void>(
(desktopKey, _) => DesktopDashboardPage(
balancePage: getIt.get<BalancePage>(),
dashboardViewModel: getIt.get<DashboardViewModel>(),
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
desktopKey: desktopKey,
));
balancePage: getIt.get<BalancePage>(),
dashboardViewModel: getIt.get<DashboardViewModel>(),
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
desktopKey: desktopKey,
));
getIt.registerFactory<TransactionsPage>(() => TransactionsPage(dashboardViewModel: getIt.get<DashboardViewModel>()));
getIt.registerFactory<TransactionsPage>(
() => TransactionsPage(dashboardViewModel: getIt.get<DashboardViewModel>()));
getIt.registerFactoryParam<ReceiveOptionViewModel, ReceivePageOption?, void>((pageOption, _) => ReceiveOptionViewModel(
getIt.get<AppStore>().wallet!, pageOption));
getIt.registerFactory<Setup2FAPage>(
() => Setup2FAPage(setup2FAViewModel: getIt.get<Setup2FAViewModel>()));
getIt.registerFactory<Setup2FAQRPage>(
() => Setup2FAQRPage(setup2FAViewModel: getIt.get<Setup2FAViewModel>()));
getIt.registerFactory<Modify2FAPage>(
() => Modify2FAPage(setup2FAViewModel: getIt.get<Setup2FAViewModel>()));
getIt.registerFactoryParam<ReceiveOptionViewModel, ReceivePageOption?, void>(
(pageOption, _) => ReceiveOptionViewModel(getIt.get<AppStore>().wallet!, pageOption));
getIt.registerFactoryParam<AnonInvoicePageViewModel, List<dynamic>, void>((args, _) {
final address = args.first as String;
@ -446,28 +507,27 @@ Future setup(
getIt.get<SharedPreferences>(),
pageOption,
);
});
});
getIt.registerFactoryParam<AnonPayInvoicePage, List<dynamic>, void>((List<dynamic> args, _) {
final pageOption = args.last as ReceivePageOption;
return AnonPayInvoicePage(
getIt.get<AnonInvoicePageViewModel>(param1: args),
getIt.get<ReceiveOptionViewModel>(param1: pageOption));
});
return AnonPayInvoicePage(getIt.get<AnonInvoicePageViewModel>(param1: args),
getIt.get<ReceiveOptionViewModel>(param1: pageOption));
});
getIt.registerFactory<ReceivePage>(() => ReceivePage(
addressListViewModel: getIt.get<WalletAddressListViewModel>()));
getIt.registerFactory<ReceivePage>(
() => ReceivePage(addressListViewModel: getIt.get<WalletAddressListViewModel>()));
getIt.registerFactory<AddressPage>(() => AddressPage(
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
dashboardViewModel: getIt.get<DashboardViewModel>(),
receiveOptionViewModel: getIt.get<ReceiveOptionViewModel>()));
getIt.registerFactoryParam<WalletAddressEditOrCreateViewModel, WalletAddressListItem?, void>(
(WalletAddressListItem? item, _) => WalletAddressEditOrCreateViewModel(
wallet: getIt.get<AppStore>().wallet!, item: item));
(WalletAddressListItem? item, _) =>
WalletAddressEditOrCreateViewModel(wallet: getIt.get<AppStore>().wallet!, item: item));
getIt.registerFactoryParam<AddressEditOrCreatePage, dynamic, void>(
(dynamic item, _) => AddressEditOrCreatePage(
getIt.registerFactoryParam<AddressEditOrCreatePage, dynamic, void>((dynamic item, _) =>
AddressEditOrCreatePage(
addressEditOrCreateViewModel:
getIt.get<WalletAddressEditOrCreateViewModel>(param1: item)));
@ -487,15 +547,16 @@ Future setup(
getIt.registerFactoryParam<SendPage, PaymentRequest?, void>(
(PaymentRequest? initialPaymentRequest, _) => SendPage(
sendViewModel: getIt.get<SendViewModel>(),
initialPaymentRequest: initialPaymentRequest,
));
sendViewModel: getIt.get<SendViewModel>(),
initialPaymentRequest: initialPaymentRequest,
));
getIt.registerFactory(() => SendTemplatePage(
sendTemplateViewModel: getIt.get<SendTemplateViewModel>()));
getIt.registerFactory(
() => SendTemplatePage(sendTemplateViewModel: getIt.get<SendTemplateViewModel>()));
if (DeviceInfo.instance.isMobile) {
getIt.registerFactory(() => WalletListViewModel(
getIt.registerFactory(
() => WalletListViewModel(
_walletInfoSource,
getIt.get<AppStore>(),
getIt.get<WalletLoadingService>(),
@ -505,7 +566,8 @@ Future setup(
} else {
// register wallet list view model as singleton on desktop since it can be accessed
// from multiple places at the same time (Wallets DropDown, Wallets List in settings)
getIt.registerLazySingleton(() => WalletListViewModel(
getIt.registerLazySingleton(
() => WalletListViewModel(
_walletInfoSource,
getIt.get<AppStore>(),
getIt.get<WalletLoadingService>(),
@ -514,8 +576,10 @@ Future setup(
);
}
getIt.registerFactory(() =>
WalletListPage(walletListViewModel: getIt.get<WalletListViewModel>()));
getIt.registerFactory(() => WalletListPage(
walletListViewModel: getIt.get<WalletListViewModel>(),
authService: getIt.get<AuthService>(),
));
getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet!;
@ -524,11 +588,12 @@ Future setup(
return MoneroAccountListViewModel(wallet);
}
throw Exception('Unexpected wallet type: ${wallet.type} for generate MoneroAccountListViewModel');
throw Exception(
'Unexpected wallet type: ${wallet.type} for generate MoneroAccountListViewModel');
});
getIt.registerFactory(() => MoneroAccountListPage(
accountListViewModel: getIt.get<MoneroAccountListViewModel>()));
getIt.registerFactory(
() => MoneroAccountListPage(accountListViewModel: getIt.get<MoneroAccountListViewModel>()));
/*getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet;
@ -545,16 +610,14 @@ Future setup(
moneroAccountCreationViewModel:
getIt.get<MoneroAccountEditOrCreateViewModel>()));*/
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel,
AccountListItem?, void>(
getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel, AccountListItem?, void>(
(AccountListItem? account, _) => MoneroAccountEditOrCreateViewModel(
monero!.getAccountList(getIt.get<AppStore>().wallet!),
haven?.getAccountList(getIt.get<AppStore>().wallet!),
wallet: getIt.get<AppStore>().wallet!,
accountListItem: account));
getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem?,
void>(
getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem?, void>(
(AccountListItem? account, _) => MoneroAccountEditOrCreatePage(
moneroAccountCreationViewModel:
getIt.get<MoneroAccountEditOrCreateViewModel>(param1: account)));
@ -575,41 +638,37 @@ Future setup(
return SecuritySettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AuthService>());
});
getIt
.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
getIt.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
getIt.registerFactoryParam<WalletSeedPage, bool, void>(
(bool isWalletCreated, _) => WalletSeedPage(
getIt.get<WalletSeedViewModel>(),
isNewWalletCreated: isWalletCreated));
getIt.registerFactoryParam<WalletSeedPage, bool, void>((bool isWalletCreated, _) =>
WalletSeedPage(getIt.get<WalletSeedViewModel>(), isNewWalletCreated: isWalletCreated));
getIt
.registerFactory(() => WalletKeysViewModel(getIt.get<AppStore>()));
getIt.registerFactory(() => WalletKeysViewModel(getIt.get<AppStore>()));
getIt.registerFactory(() => WalletKeysPage(getIt.get<WalletKeysViewModel>()));
getIt.registerFactoryParam<ContactViewModel, ContactRecord?, void>(
(ContactRecord? contact, _) =>
ContactViewModel(_contactSource, contact: contact));
(ContactRecord? contact, _) => ContactViewModel(_contactSource, contact: contact));
getIt.registerFactoryParam<ContactListViewModel, CryptoCurrency?, void>(
(CryptoCurrency? cur, _) => ContactListViewModel(_contactSource, _walletInfoSource, cur));
getIt.registerFactoryParam<ContactListPage, CryptoCurrency?, void>((CryptoCurrency? cur, _)
=> ContactListPage(getIt.get<ContactListViewModel>(param1: cur)));
getIt.registerFactoryParam<ContactListPage, CryptoCurrency?, void>(
(CryptoCurrency? cur, _) => ContactListPage(getIt.get<ContactListViewModel>(param1: cur)));
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
(ContactRecord? contact, _) =>
ContactPage(getIt.get<ContactViewModel>(param1: contact)));
(ContactRecord? contact, _) => ContactPage(getIt.get<ContactViewModel>(param1: contact)));
getIt.registerFactory(() {
final appStore = getIt.get<AppStore>();
return NodeListViewModel(_nodeSource, appStore);
});
getIt.registerFactory(() => ConnectionSyncPage(getIt.get<NodeListViewModel>(), getIt.get<DashboardViewModel>()));
getIt.registerFactory(
() => ConnectionSyncPage(getIt.get<NodeListViewModel>(), getIt.get<DashboardViewModel>()));
getIt.registerFactory(() => SecurityBackupPage(getIt.get<SecuritySettingsViewModel>()));
getIt.registerFactory(
() => SecurityBackupPage(getIt.get<SecuritySettingsViewModel>(), getIt.get<AuthService>()));
getIt.registerFactory(() => PrivacyPage(getIt.get<PrivacySettingsViewModel>()));
@ -617,41 +676,38 @@ Future setup(
getIt.registerFactory(() => OtherSettingsPage(getIt.get<OtherSettingsViewModel>()));
getIt.registerFactoryParam<NodeCreateOrEditViewModel, WalletType?, void>(
(WalletType? type, _) => NodeCreateOrEditViewModel(
_nodeSource,
type ?? getIt.get<AppStore>().wallet!.type,
getIt.get<SettingsStore>()
));
getIt.registerFactoryParam<NodeCreateOrEditViewModel, WalletType?, void>((WalletType? type, _) =>
NodeCreateOrEditViewModel(
_nodeSource, type ?? getIt.get<AppStore>().wallet!.type, getIt.get<SettingsStore>()));
getIt.registerFactoryParam<NodeCreateOrEditPage, Node?, bool?>(
(Node? editingNode, bool? isSelected) => NodeCreateOrEditPage(
(Node? editingNode, bool? isSelected) => NodeCreateOrEditPage(
nodeCreateOrEditViewModel: getIt.get<NodeCreateOrEditViewModel>(),
editingNode: editingNode,
isSelected: isSelected));
getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider(
settingsStore: getIt.get<AppStore>().settingsStore,
wallet: getIt.get<AppStore>().wallet!,
));
settingsStore: getIt.get<AppStore>().settingsStore,
wallet: getIt.get<AppStore>().wallet!,
));
getIt.registerFactory(() => OnRamperPage(getIt.get<OnRamperBuyProvider>()));
getIt.registerFactory<PayfuraBuyProvider>(() => PayfuraBuyProvider(
settingsStore: getIt.get<AppStore>().settingsStore,
wallet: getIt.get<AppStore>().wallet!,
));
settingsStore: getIt.get<AppStore>().settingsStore,
wallet: getIt.get<AppStore>().wallet!,
));
getIt.registerFactory(() => PayFuraPage(getIt.get<PayfuraBuyProvider>()));
getIt.registerFactory(() => ExchangeViewModel(
getIt.get<AppStore>().wallet!,
_tradesSource,
getIt.get<ExchangeTemplateStore>(),
getIt.get<TradesStore>(),
getIt.get<AppStore>().settingsStore,
getIt.get<SharedPreferences>(),
));
getIt.get<AppStore>().wallet!,
_tradesSource,
getIt.get<ExchangeTemplateStore>(),
getIt.get<TradesStore>(),
getIt.get<AppStore>().settingsStore,
getIt.get<SharedPreferences>(),
));
getIt.registerFactory(() => ExchangeTradeViewModel(
wallet: getIt.get<AppStore>().wallet!,
@ -661,17 +717,14 @@ Future setup(
getIt.registerFactory(() => ExchangePage(getIt.get<ExchangeViewModel>()));
getIt.registerFactory(
() => ExchangeConfirmPage(tradesStore: getIt.get<TradesStore>()));
getIt.registerFactory(() => ExchangeTradePage(
exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
getIt.registerFactory(() => ExchangeConfirmPage(tradesStore: getIt.get<TradesStore>()));
getIt.registerFactory(
() => ExchangeTemplatePage(getIt.get<ExchangeViewModel>()));
() => ExchangeTradePage(exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
getIt.registerFactoryParam<WalletService, WalletType, void>(
(WalletType param1, __) {
getIt.registerFactory(() => ExchangeTemplatePage(getIt.get<ExchangeViewModel>()));
getIt.registerFactoryParam<WalletService, WalletType, void>((WalletType param1, __) {
switch (param1) {
case WalletType.haven:
return haven!.createHavenWalletService(_walletInfoSource);
@ -690,13 +743,12 @@ Future setup(
}
});
getIt.registerFactory<SetupPinCodeViewModel>(() => SetupPinCodeViewModel(
getIt.get<AuthService>(), getIt.get<SettingsStore>()));
getIt.registerFactory<SetupPinCodeViewModel>(
() => SetupPinCodeViewModel(getIt.get<AuthService>(), getIt.get<SettingsStore>()));
getIt.registerFactoryParam<SetupPinCodePage,
void Function(PinCodeState<PinCodeWidget>, String), void>(
(onSuccessfulPinSetup, _) => SetupPinCodePage(
getIt.get<SetupPinCodeViewModel>(),
getIt.registerFactoryParam<SetupPinCodePage, void Function(PinCodeState<PinCodeWidget>, String),
void>(
(onSuccessfulPinSetup, _) => SetupPinCodePage(getIt.get<SetupPinCodeViewModel>(),
onSuccessfulPinSetup: onSuccessfulPinSetup));
getIt.registerFactory(() => RescanViewModel(getIt.get<AppStore>().wallet!));
@ -705,17 +757,16 @@ Future setup(
getIt.registerFactory(() => FaqPage(getIt.get<SettingsStore>()));
getIt.registerFactoryParam<WalletRestoreViewModel, WalletType, void>(
(type, _) => WalletRestoreViewModel(getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
getIt.registerFactoryParam<WalletRestoreViewModel, WalletType, void>((type, _) =>
WalletRestoreViewModel(
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
type: type));
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) =>
WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>(
(type, _) => WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
getIt
.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>(
(TransactionInfo transactionInfo, _) {
getIt.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>(
(TransactionInfo transactionInfo, _) {
final wallet = getIt.get<AppStore>().wallet!;
return TransactionDetailsViewModel(
transactionInfo: transactionInfo,
@ -729,15 +780,16 @@ Future setup(
transactionDetailsViewModel:
getIt.get<TransactionDetailsViewModel>(param1: transactionInfo)));
getIt.registerFactoryParam<NewWalletTypePage,
void Function(BuildContext, WalletType), void>(
getIt.registerFactoryParam<NewWalletTypePage, void Function(BuildContext, WalletType), void>(
(param1, _) => NewWalletTypePage(onTypeSelected: param1));
getIt.registerFactoryParam<PreSeedPage, WalletType, void>(
(WalletType type, _) => PreSeedPage(type));
getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>((trade, _) =>
TradeDetailsViewModel(tradeForDetails: trade, trades: _tradesSource,
TradeDetailsViewModel(
tradeForDetails: trade,
trades: _tradesSource,
settingsStore: getIt.get<SettingsStore>()));
getIt.registerFactory(() => BackupService(
@ -746,35 +798,33 @@ Future setup(
getIt.get<KeyService>(),
getIt.get<SharedPreferences>()));
getIt.registerFactory(() => BackupViewModel(getIt.get<SecureStorage>(),
getIt.get<SecretStore>(), getIt.get<BackupService>()));
getIt.registerFactory(() => BackupViewModel(
getIt.get<SecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupService>()));
getIt.registerFactory(() => BackupPage(getIt.get<BackupViewModel>()));
getIt.registerFactory(
() => EditBackupPasswordViewModel(getIt.get<SecureStorage>(), getIt.get<SecretStore>()));
getIt.registerFactory(() =>
EditBackupPasswordViewModel(getIt.get<SecureStorage>(), getIt.get<SecretStore>()));
getIt.registerFactory(
() => EditBackupPasswordPage(getIt.get<EditBackupPasswordViewModel>()));
getIt.registerFactory(() => EditBackupPasswordPage(getIt.get<EditBackupPasswordViewModel>()));
getIt.registerFactory(() => RestoreOptionsPage());
getIt.registerFactoryParam<RestoreOptionsPage, bool, void>(
(bool isNewInstall, _) => RestoreOptionsPage(isNewInstall: isNewInstall));
getIt.registerFactory(
() => RestoreFromBackupViewModel(getIt.get<BackupService>()));
getIt.registerFactory(() => RestoreFromBackupViewModel(getIt.get<BackupService>()));
getIt.registerFactory(
() => RestoreFromBackupPage(getIt.get<RestoreFromBackupViewModel>()));
getIt.registerFactory(() => RestoreFromBackupPage(getIt.get<RestoreFromBackupViewModel>()));
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>(
(Trade trade, _) => TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
getIt.registerFactory(() => BuyAmountViewModel());
getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet;
return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(),
getIt.get<SettingsStore>(), getIt.get<BuyAmountViewModel>(),
return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(), getIt.get<SettingsStore>(),
getIt.get<BuyAmountViewModel>(),
wallet: wallet!);
});
@ -786,7 +836,8 @@ Future setup(
final url = args.first as String;
final buyViewModel = args[1] as BuyViewModel;
return BuyWebViewPage(buyViewModel: buyViewModel, ordersStore: getIt.get<OrdersStore>(), url: url);
return BuyWebViewPage(
buyViewModel: buyViewModel, ordersStore: getIt.get<OrdersStore>(), url: url);
});
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) {
@ -795,8 +846,8 @@ Future setup(
return OrderDetailsViewModel(wallet: wallet!, orderForDetails: order);
});
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
getIt.registerFactoryParam<OrderDetailsPage, Order, void>(
(Order order, _) => OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
getIt.registerFactory(() => SupportViewModel());
@ -805,20 +856,18 @@ Future setup(
getIt.registerFactory(() {
final wallet = getIt.get<AppStore>().wallet;
return UnspentCoinsListViewModel(
wallet: wallet!, unspentCoinsInfo: _unspentCoinsInfoSource!);
return UnspentCoinsListViewModel(wallet: wallet!, unspentCoinsInfo: _unspentCoinsInfoSource!);
});
getIt.registerFactory(() => UnspentCoinsListPage(
unspentCoinsListViewModel: getIt.get<UnspentCoinsListViewModel>()));
getIt.registerFactory(() =>
UnspentCoinsListPage(unspentCoinsListViewModel: getIt.get<UnspentCoinsListViewModel>()));
getIt.registerFactoryParam<UnspentCoinsDetailsViewModel, UnspentCoinsItem,
UnspentCoinsListViewModel>(
(item, model) => UnspentCoinsDetailsViewModel(
unspentCoinsItem: item, unspentCoinsListViewModel: model));
(item, model) =>
UnspentCoinsDetailsViewModel(unspentCoinsItem: item, unspentCoinsListViewModel: model));
getIt.registerFactoryParam<UnspentCoinsDetailsPage, List, void>(
(List args, _) {
getIt.registerFactoryParam<UnspentCoinsDetailsPage, List, void>((List args, _) {
final item = args.first as UnspentCoinsItem;
final unspentCoinsListViewModel = args[1] as UnspentCoinsListViewModel;
@ -829,11 +878,11 @@ Future setup(
getIt.registerFactory(() => YatService());
getIt.registerFactory(() => AddressResolver(yatService: getIt.get<YatService>(),
walletType: getIt.get<AppStore>().wallet!.type));
getIt.registerFactory(() => AddressResolver(
yatService: getIt.get<YatService>(), walletType: getIt.get<AppStore>().wallet!.type));
getIt.registerFactoryParam<FullscreenQRPage, String, int?>(
(String qrData, int? version) => FullscreenQRPage(qrData: qrData, version: version,));
getIt.registerFactoryParam<FullscreenQRPage, QrViewData, void>(
(QrViewData viewData, _) => FullscreenQRPage(qrViewData: viewData));
getIt.registerFactory(() => IoniaApi());
@ -842,26 +891,24 @@ Future setup(
getIt.registerFactory<IoniaService>(
() => IoniaService(getIt.get<SecureStorage>(), getIt.get<IoniaApi>()));
getIt.registerFactory<IoniaAnyPay>(
() => IoniaAnyPay(
getIt.get<IoniaService>(),
getIt.get<AnyPayApi>(),
getIt.get<AppStore>().wallet!));
getIt.registerFactory<IoniaAnyPay>(() => IoniaAnyPay(
getIt.get<IoniaService>(), getIt.get<AnyPayApi>(), getIt.get<AppStore>().wallet!));
getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get<IoniaService>()));
getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get<IoniaService>()));
getIt.registerFactoryParam<IoniaMerchPurchaseViewModel, double, IoniaMerchant>((double amount, merchant) {
getIt.registerFactoryParam<IoniaMerchPurchaseViewModel, double, IoniaMerchant>(
(double amount, merchant) {
return IoniaMerchPurchaseViewModel(
ioniaAnyPayService: getIt.get<IoniaAnyPay>(),
amount: amount,
ioniaMerchant: merchant,
sendViewModel: getIt.get<SendViewModel>()
);
ioniaAnyPayService: getIt.get<IoniaAnyPay>(),
amount: amount,
ioniaMerchant: merchant,
sendViewModel: getIt.get<SendViewModel>());
});
getIt.registerFactoryParam<IoniaBuyCardViewModel, IoniaMerchant, void>((IoniaMerchant merchant, _) {
getIt.registerFactoryParam<IoniaBuyCardViewModel, IoniaMerchant, void>(
(IoniaMerchant merchant, _) {
return IoniaBuyCardViewModel(ioniaMerchant: merchant);
});
@ -889,43 +936,45 @@ Future setup(
getIt.registerFactoryParam<IoniaBuyGiftCardDetailPage, List, void>((List args, _) {
final amount = args.first as double;
final merchant = args.last as IoniaMerchant;
return IoniaBuyGiftCardDetailPage(getIt.get<IoniaMerchPurchaseViewModel>(param1: amount, param2: merchant));
return IoniaBuyGiftCardDetailPage(
getIt.get<IoniaMerchPurchaseViewModel>(param1: amount, param2: merchant));
});
getIt.registerFactoryParam<IoniaGiftCardDetailsViewModel, IoniaGiftCard, void>((IoniaGiftCard giftCard, _) {
return IoniaGiftCardDetailsViewModel(
ioniaService: getIt.get<IoniaService>(),
giftCard: giftCard);
getIt.registerFactoryParam<IoniaGiftCardDetailsViewModel, IoniaGiftCard, void>(
(IoniaGiftCard giftCard, _) {
return IoniaGiftCardDetailsViewModel(
ioniaService: getIt.get<IoniaService>(), giftCard: giftCard);
});
getIt.registerFactoryParam<IoniaCustomTipViewModel, List, void>((List args, _) {
final amount = args[0] as double;
final merchant = args[1] as IoniaMerchant;
final tip = args[2] as IoniaTip;
getIt.registerFactoryParam<IoniaCustomTipViewModel, List, void>((List args, _) {
final amount = args[0] as double;
final merchant = args[1] as IoniaMerchant;
final tip = args[2] as IoniaTip;
return IoniaCustomTipViewModel(amount: amount, tip: tip, ioniaMerchant: merchant);
return IoniaCustomTipViewModel(amount: amount, tip: tip, ioniaMerchant: merchant);
});
getIt.registerFactoryParam<IoniaGiftCardDetailPage, IoniaGiftCard, void>((IoniaGiftCard giftCard, _) {
return IoniaGiftCardDetailPage(getIt.get<IoniaGiftCardDetailsViewModel>(param1: giftCard));
getIt.registerFactoryParam<IoniaGiftCardDetailPage, IoniaGiftCard, void>(
(IoniaGiftCard giftCard, _) {
return IoniaGiftCardDetailPage(getIt.get<IoniaGiftCardDetailsViewModel>(param1: giftCard));
});
getIt.registerFactoryParam<IoniaMoreOptionsPage, List, void>((List args, _){
getIt.registerFactoryParam<IoniaMoreOptionsPage, List, void>((List args, _) {
final giftCard = args.first as IoniaGiftCard;
return IoniaMoreOptionsPage(giftCard);
});
getIt.registerFactoryParam<IoniaCustomRedeemViewModel, IoniaGiftCard, void>((IoniaGiftCard giftCard, _)
=> IoniaCustomRedeemViewModel(giftCard: giftCard, ioniaService: getIt.get<IoniaService>()));
getIt.registerFactoryParam<IoniaCustomRedeemViewModel, IoniaGiftCard, void>(
(IoniaGiftCard giftCard, _) =>
IoniaCustomRedeemViewModel(giftCard: giftCard, ioniaService: getIt.get<IoniaService>()));
getIt.registerFactoryParam<IoniaCustomRedeemPage, List, void>((List args, _){
getIt.registerFactoryParam<IoniaCustomRedeemPage, List, void>((List args, _) {
final giftCard = args.first as IoniaGiftCard;
return IoniaCustomRedeemPage(getIt.get<IoniaCustomRedeemViewModel>(param1: giftCard) );
return IoniaCustomRedeemPage(getIt.get<IoniaCustomRedeemViewModel>(param1: giftCard));
});
getIt.registerFactoryParam<IoniaCustomTipPage, List, void>((List args, _) {
return IoniaCustomTipPage(getIt.get<IoniaCustomTipViewModel>(param1: args));
});
@ -940,42 +989,44 @@ Future setup(
getIt.registerFactory(() => IoniaAccountCardsPage(getIt.get<IoniaAccountViewModel>()));
getIt.registerFactory(() => AnonPayApi(useTorOnly: getIt.get<SettingsStore>().exchangeStatus == ExchangeApiMode.torOnly,
wallet: getIt.get<AppStore>().wallet!)
);
getIt.registerFactory(() => AnonPayApi(
useTorOnly: getIt.get<SettingsStore>().exchangeStatus == ExchangeApiMode.torOnly,
wallet: getIt.get<AppStore>().wallet!));
getIt.registerFactory(() => DesktopWalletSelectionDropDown(getIt.get<WalletListViewModel>()));
getIt.registerFactory(() =>
DesktopWalletSelectionDropDown(getIt.get<WalletListViewModel>(), getIt.get<AuthService>()));
getIt.registerFactory(() => DesktopSidebarViewModel());
getIt.registerFactoryParam<AnonpayDetailsViewModel, AnonpayInvoiceInfo, void>(
(AnonpayInvoiceInfo anonpayInvoiceInfo, _)
=> AnonpayDetailsViewModel(
anonPayApi: getIt.get<AnonPayApi>(),
anonpayInvoiceInfo: anonpayInvoiceInfo,
settingsStore: getIt.get<SettingsStore>(),
));
(AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsViewModel(
anonPayApi: getIt.get<AnonPayApi>(),
anonpayInvoiceInfo: anonpayInvoiceInfo,
settingsStore: getIt.get<SettingsStore>(),
));
getIt.registerFactoryParam<AnonPayReceivePage, AnonpayInfoBase, void>(
(AnonpayInfoBase anonpayInvoiceInfo, _) => AnonPayReceivePage(invoiceInfo: anonpayInvoiceInfo));
(AnonpayInfoBase anonpayInvoiceInfo, _) =>
AnonPayReceivePage(invoiceInfo: anonpayInvoiceInfo));
getIt.registerFactoryParam<AnonpayDetailsPage, AnonpayInvoiceInfo, void>(
(AnonpayInvoiceInfo anonpayInvoiceInfo, _)
=> AnonpayDetailsPage(anonpayDetailsViewModel: getIt.get<AnonpayDetailsViewModel>(param1: anonpayInvoiceInfo)));
(AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsPage(
anonpayDetailsViewModel: getIt.get<AnonpayDetailsViewModel>(param1: anonpayInvoiceInfo)));
getIt.registerFactoryParam<IoniaPaymentStatusViewModel, IoniaAnyPayPaymentInfo, AnyPayPaymentCommittedInfo>(
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo)
=> IoniaPaymentStatusViewModel(
getIt.get<IoniaService>(),
paymentInfo: paymentInfo,
committedInfo: committedInfo));
getIt.registerFactoryParam<IoniaPaymentStatusViewModel, IoniaAnyPayPaymentInfo,
AnyPayPaymentCommittedInfo>(
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) =>
IoniaPaymentStatusViewModel(getIt.get<IoniaService>(),
paymentInfo: paymentInfo, committedInfo: committedInfo));
getIt.registerFactoryParam<IoniaPaymentStatusPage, IoniaAnyPayPaymentInfo, AnyPayPaymentCommittedInfo>(
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo)
=> IoniaPaymentStatusPage(getIt.get<IoniaPaymentStatusViewModel>(param1: paymentInfo, param2: committedInfo)));
getIt.registerFactoryParam<IoniaPaymentStatusPage, IoniaAnyPayPaymentInfo,
AnyPayPaymentCommittedInfo>(
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) =>
IoniaPaymentStatusPage(
getIt.get<IoniaPaymentStatusViewModel>(param1: paymentInfo, param2: committedInfo)));
getIt.registerFactoryParam<AdvancedPrivacySettingsViewModel, WalletType, void>((type, _) =>
AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>()));
getIt.registerFactoryParam<AdvancedPrivacySettingsViewModel, WalletType, void>(
(type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>()));
getIt.registerFactoryParam<WalletUnlockLoadableViewModel, WalletUnlockArguments, void>((args, _) {
final currentWalletName = getIt

View file

@ -42,6 +42,13 @@ Future defaultSettingsMigration(
// check current nodes for nullability regardless of the version
await checkCurrentNodes(nodes, sharedPreferences);
final isNewInstall = sharedPreferences
.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion) == null;
await sharedPreferences.setBool(
PreferencesKey.isNewInstall, isNewInstall);
final currentVersion = sharedPreferences
.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion) ??
0;

View file

@ -26,7 +26,9 @@ class LanguageService {
'bg': 'Български (Bulgarian)',
'cs': 'čeština (Czech)',
'ur': 'اردو (Urdu)',
'id': 'Bahasa Indonesia (Indonesian)'
'id': 'Bahasa Indonesia (Indonesian)',
'yo': 'Yorùbá (Yoruba)',
'ha': 'Hausa Najeriya (Nigeria)'
};
static const Map<String, String> localeCountryCode = {
@ -52,7 +54,9 @@ class LanguageService {
'bg': 'bgr',
'cs': 'czk',
'ur': 'pak',
'id': 'idn'
'id': 'idn',
'yo': 'yor',
'ha': 'hau'
};
static final list = <String, String> {};

View file

@ -47,23 +47,23 @@ class MainActions {
switch (walletType) {
case WalletType.bitcoin:
case WalletType.litecoin:
if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.onramperPage);
} else {
final uri = getIt
.get<OnRamperBuyProvider>()
.requestUrl();
await launchUrl(uri);
if (viewModel.isEnabledBuyAction) {
if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.onramperPage);
} else {
final uri = getIt.get<OnRamperBuyProvider>().requestUrl();
await launchUrl(uri);
}
}
break;
case WalletType.monero:
if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.payfuraPage);
} else {
final uri = getIt
.get<PayfuraBuyProvider>()
.requestUrl();
await launchUrl(uri);
if (viewModel.isEnabledBuyAction) {
if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.payfuraPage);
} else {
final uri = getIt.get<PayfuraBuyProvider>().requestUrl();
await launchUrl(uri);
}
}
break;
default:
@ -118,12 +118,14 @@ class MainActions {
switch (walletType) {
case WalletType.bitcoin:
final moonPaySellProvider = MoonPaySellProvider();
final uri = await moonPaySellProvider.requestUrl(
currency: viewModel.wallet.currency,
refundWalletAddress: viewModel.wallet.walletAddresses.address,
);
await launchUrl(uri);
if (viewModel.isEnabledSellAction) {
final moonPaySellProvider = MoonPaySellProvider();
final uri = await moonPaySellProvider.requestUrl(
currency: viewModel.wallet.currency,
refundWalletAddress: viewModel.wallet.walletAddresses.address,
);
await launchUrl(uri);
}
break;
default:
await showPopUp<void>(

View file

@ -33,7 +33,7 @@ class AddressResolver {
final addressPattern = AddressValidator.getAddressFromStringPattern(type);
if (addressPattern == null) {
throw 'Unexpected token: $type for getAddressFromStringPattern';
throw Exception('Unexpected token: $type for getAddressFromStringPattern');
}
final match = RegExp(addressPattern).firstMatch(raw);

View file

@ -9,9 +9,15 @@ class PreferencesKey {
static const currentTransactionPriorityKeyLegacy = 'current_fee_priority';
static const currentBalanceDisplayModeKey = 'current_balance_display_mode';
static const shouldSaveRecipientAddressKey = 'save_recipient_address';
static const isAppSecureKey = 'is_app_secure';
static const disableBuyKey = 'disable_buy';
static const disableSellKey = 'disable_sell';
static const currentFiatApiModeKey = 'current_fiat_api_mode';
static const allowBiometricalAuthenticationKey =
'allow_biometrical_authentication';
static const useTOTP2FA = 'use_totp_2fa';
static const failedTotpTokenTrials = 'failed_token_trials';
static const totpSecretKey = 'totp_qr_secret_key';
static const disableExchangeKey = 'disable_exchange';
static const exchangeStatusKey = 'exchange_status';
static const currentTheme = 'current_theme';
@ -40,6 +46,8 @@ class PreferencesKey {
static const exchangeProvidersSelection = 'exchange-providers-selection';
static const clearnetDonationLink = 'clearnet_donation_link';
static const onionDonationLink = 'onion_donation_link';
static const onionDonationLink = 'onion_donation_link';
static const lastSeenAppVersion = 'last_seen_app_version';
static const shouldShowMarketPlaceInDashboard = 'should_show_marketplace_in_dashboard';
static const isNewInstall = 'is_new_install';
}

View file

@ -0,0 +1,11 @@
class QrViewData {
final int? version;
final String? heroTag;
final String data;
QrViewData({
this.version,
this.heroTag,
required this.data,
});
}

View file

@ -4,14 +4,15 @@ part 'exchange_template.g.dart';
@HiveType(typeId: ExchangeTemplate.typeId)
class ExchangeTemplate extends HiveObject {
ExchangeTemplate({
required this.amountRaw,
required this.depositCurrencyRaw,
required this.receiveCurrencyRaw,
required this.providerRaw,
required this.depositAddressRaw,
required this.receiveAddressRaw
});
ExchangeTemplate(
{required this.amountRaw,
required this.depositCurrencyRaw,
required this.receiveCurrencyRaw,
required this.providerRaw,
required this.depositAddressRaw,
required this.receiveAddressRaw,
required this.depositCurrencyTitleRaw,
required this.receiveCurrencyTitleRaw});
static const typeId = 7;
static const boxName = 'ExchangeTemplate';
@ -34,6 +35,12 @@ class ExchangeTemplate extends HiveObject {
@HiveField(5)
String? receiveAddressRaw;
@HiveField(6)
String? depositCurrencyTitleRaw;
@HiveField(7)
String? receiveCurrencyTitleRaw;
String get amount => amountRaw ?? '';
String get depositCurrency => depositCurrencyRaw ?? '';
@ -45,4 +52,8 @@ class ExchangeTemplate extends HiveObject {
String get depositAddress => depositAddressRaw ?? '';
String get receiveAddress => receiveAddressRaw ?? '';
}
String get depositCurrencyTitle => depositCurrencyTitleRaw ?? '';
String get receiveCurrencyTitle => receiveCurrencyTitleRaw ?? '';
}

View file

@ -29,9 +29,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
CryptoCurrency.dcr,
CryptoCurrency.kmd,
CryptoCurrency.mkr,
CryptoCurrency.near,
CryptoCurrency.oxt,
CryptoCurrency.paxg,
CryptoCurrency.pivx,
CryptoCurrency.rune,
CryptoCurrency.rvn,
@ -300,6 +298,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
return 'usdcsol';
case CryptoCurrency.maticpoly:
return 'polygon';
case CryptoCurrency.btcln:
return 'ln';
default:
return currency.title.toLowerCase();
}

View file

@ -285,6 +285,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
return 'ERC20';
case 'TRX':
return 'TRC20';
case 'LN':
return 'Lightning';
default:
return tag.toLowerCase();
}

940
lib/locales/hausa_intl.dart Normal file
View file

@ -0,0 +1,940 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/date_symbol_data_custom.dart' as date_symbol_data_custom;
import 'package:intl/date_symbols.dart' as intl;
import 'package:intl/intl.dart' as intl;
// #docregion Date
const haLocaleDatePatterns = {
'd': 'd.',
'E': 'ccc',
'EEEE': 'cccc',
'LLL': 'LLL',
// #enddocregion Date
'LLLL': 'LLLL',
'M': 'L.',
'Md': 'd.M.',
'MEd': 'EEE d.M.',
'MMM': 'LLL',
'MMMd': 'd. MMM',
'MMMEd': 'EEE d. MMM',
'MMMM': 'LLLL',
'MMMMd': 'd. MMMM',
'MMMMEEEEd': 'EEEE d. MMMM',
'QQQ': 'QQQ',
'QQQQ': 'QQQQ',
'y': 'y',
'yM': 'M.y',
'yMd': 'd.M.y',
'yMEd': 'EEE d.MM.y',
'yMMM': 'MMM y',
'yMMMd': 'd. MMM y',
'yMMMEd': 'EEE d. MMM y',
'yMMMM': 'MMMM y',
'yMMMMd': 'd. MMMM y',
'yMMMMEEEEd': 'EEEE d. MMMM y',
'yQQQ': 'QQQ y',
'yQQQQ': 'QQQQ y',
'H': 'HH',
'Hm': 'HH:mm',
'Hms': 'HH:mm:ss',
'j': 'HH',
'jm': 'HH:mm',
'jms': 'HH:mm:ss',
'jmv': 'HH:mm v',
'jmz': 'HH:mm z',
'jz': 'HH z',
'm': 'm',
'ms': 'mm:ss',
's': 's',
'v': 'v',
'z': 'z',
'zzzz': 'zzzz',
'ZZZZ': 'ZZZZ',
};
// #docregion Date2
const haDateSymbols = {
'NAME': 'ha',
'ERAS': <dynamic>[
'f.Kr.',
'e.Kr.',
],
// #enddocregion Date2
'ERANAMES': <dynamic>[
'kafin Kristi',
'bayan Kristi',
],
'NARROWMONTHS': <dynamic>[
'J',
'F',
'M',
'A',
'M',
'J',
'J',
'A',
'S',
'O',
'N',
'D',
],
'STANDALONENARROWMONTHS': <dynamic>[
'J',
'F',
'M',
'A',
'M',
'J',
'J',
'A',
'S',
'O',
'N',
'D',
],
'MONTHS': <dynamic>[
'janairu',
'faburairu',
'maris',
'afrilu',
'mayu',
'yuni',
'yuli',
'agusta',
'satumba',
'oktoba',
'nuwamba',
'disamba',
],
'STANDALONEMONTHS': <dynamic>[
'janairu',
'faburairu',
'maris',
'afrilu',
'mayu',
'yuni',
'yuli',
'agusta',
'satumba',
'oktoba',
'nuwamba',
'disamba',
],
'SHORTMONTHS': <dynamic>[
'jan.',
'feb.',
'mar.',
'apr.',
'mai',
'jun.',
'jul.',
'aug.',
'sep.',
'okt.',
'nov.',
'des.',
],
'STANDALONESHORTMONTHS': <dynamic>[
'jan',
'feb',
'mar',
'apr',
'mai',
'jun',
'jul',
'aug',
'sep',
'okt',
'nov',
'des',
],
'WEEKDAYS': <dynamic>[
'lahadi',
'litinin',
'talata',
'laraba',
'alhamis',
'jummaʼa',
'asabar',
],
'STANDALONEWEEKDAYS': <dynamic>[
'lahadi',
'litinin',
'talata',
'laraba',
'alhamis',
'jummaʼa',
'asabar',
],
'SHORTWEEKDAYS': <dynamic>[
'lah.',
'lit.',
'tal.',
'lar.',
'alh.',
'jum.',
'asa.',
],
'STANDALONESHORTWEEKDAYS': <dynamic>[
'lah.',
'lit.',
'tal.',
'lar.',
'alh.',
'jum.',
'asa.',
],
'NARROWWEEKDAYS': <dynamic>[
'L',
'L',
'T',
'L',
'A',
'J',
'A',
],
'STANDALONENARROWWEEKDAYS': <dynamic>[
'L',
'L',
'T',
'L',
'A',
'J',
'A',
],
'SHORTQUARTERS': <dynamic>[
'K1',
'K2',
'K3',
'K4',
],
'QUARTERS': <dynamic>[
'1. quarter',
'2. quarter',
'3. quarter',
'4. quarter',
],
'AMPMS': <dynamic>[
'a.m.',
'p.m.',
],
'DATEFORMATS': <dynamic>[
'EEEE d. MMMM y',
'd. MMMM y',
'd. MMM y',
'dd.MM.y',
],
'TIMEFORMATS': <dynamic>[
'HH:mm:ss zzzz',
'HH:mm:ss z',
'HH:mm:ss',
'HH:mm',
],
'AVAILABLEFORMATS': null,
'FIRSTDAYOFWEEK': 0,
'WEEKENDRANGE': <dynamic>[
5,
6,
],
'FIRSTWEEKCUTOFFDAY': 3,
'DATETIMEFORMATS': <dynamic>[
'{1} {0}',
'{1} \'kl\'. {0}',
'{1}, {0}',
'{1}, {0}',
],
};
// #docregion Delegate
class _HaMaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
const _HaMaterialLocalizationsDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'ha';
@override
Future<MaterialLocalizations> load(Locale locale) async {
final String localeName = intl.Intl.canonicalizedLocale(locale.toString());
// The locale (in this case `ha`) needs to be initialized into the custom
// date symbols and patterns setup that Flutter uses.
date_symbol_data_custom.initializeDateFormattingCustom(
locale: localeName,
patterns: haLocaleDatePatterns,
symbols: intl.DateSymbols.deserializeFromMap(haDateSymbols),
);
return SynchronousFuture<MaterialLocalizations>(
HaMaterialLocalizations(
localeName: localeName,
// The `intl` library's NumberFormat class is generated from CLDR data
// (see https://github.com/dart-lang/intl/blob/master/lib/number_symbols_data.dart).
// Unfortunately, there is no way to use a locale that isn't defined in
// this map and the only way to work around this is to use a listed
// locale's NumberFormat symbols. So, here we use the number formats
// for 'en_US' instead.
decimalFormat: intl.NumberFormat('#,##0.###', 'en_US'),
twoDigitZeroPaddedFormat: intl.NumberFormat('00', 'en_US'),
// DateFormat here will use the symbols and patterns provided in the
// `date_symbol_data_custom.initializeDateFormattingCustom` call above.
// However, an alternative is to simply use a supported locale's
// DateFormat symbols, similar to NumberFormat above.
fullYearFormat: intl.DateFormat('y', localeName),
compactDateFormat: intl.DateFormat('yMd', localeName),
shortDateFormat: intl.DateFormat('yMMMd', localeName),
mediumDateFormat: intl.DateFormat('EEE, MMM d', localeName),
longDateFormat: intl.DateFormat('EEEE, MMMM d, y', localeName),
yearMonthFormat: intl.DateFormat('MMMM y', localeName),
shortMonthDayFormat: intl.DateFormat('MMM d', localeName),
),
);
}
@override
bool shouldReload(_HaMaterialLocalizationsDelegate old) => false;
}
// #enddocregion Delegate
class HaMaterialLocalizations extends GlobalMaterialLocalizations {
const HaMaterialLocalizations({
super.localeName = 'ha',
required super.fullYearFormat,
required super.compactDateFormat,
required super.shortDateFormat,
required super.mediumDateFormat,
required super.longDateFormat,
required super.yearMonthFormat,
required super.shortMonthDayFormat,
required super.decimalFormat,
required super.twoDigitZeroPaddedFormat,
});
// #docregion Getters
@override
String get moreButtonTooltip => r'Zaɓi';
@override
String get aboutListTileTitleRaw => r'Dake ɓoye $applicationname';
@override
String get alertDialogLabel => r'Alert';
// #enddocregion Getters
@override
String get anteMeridiemAbbreviation => r'AM';
@override
String get backButtonTooltip => r'Farawa';
@override
String get cancelButtonLabel => r'KANƘO';
@override
String get closeButtonLabel => r'SHIGA';
@override
String get closeButtonTooltip => r'Shiga';
@override
String get collapsedIconTapHint => r'Fara';
@override
String get continueButtonLabel => r'CI GABA';
@override
String get copyButtonLabel => r'KOPIYA';
@override
String get cutButtonLabel => r'ƘIRƘIRI';
@override
String get deleteButtonTooltip => r'Kashe';
@override
String get dialogLabel => r'Dialog';
@override
String get drawerLabel => r'Meniyar tebur';
@override
String get expandedIconTapHint => r'Faɗa';
@override
String get firstPageTooltip => r'Ta baya';
@override
String get hideAccountsLabel => r'Soke akaunti';
@override
String get lastPageTooltip => r'Ta gaba';
@override
String get licensesPageTitle => r'Lisansu';
@override
String get modalBarrierDismissLabel => r'So';
@override
String get nextMonthTooltip => r'Watan gobe';
@override
String get nextPageTooltip => r'Wani babban daidaita';
@override
String get okButtonLabel => r'OK';
@override
// A custom drawer tooltip message.
String get openAppDrawerTooltip => r'Taƙaitacciyar Menu na Nauyi';
// #docregion Raw
@override
String get pageRowsInfoTitleRaw => r'$firstRow$lastRow daga $rowCount';
@override
String get pageRowsInfoTitleApproximateRaw => r'$firstRow$lastRow daga takwas $rowCount';
// #enddocregion Raw
@override
String get pasteButtonLabel => r'BANDA';
@override
String get popupMenuLabel => r'Meniyar Kasuwa';
@override
String get menuBarMenuLabel => r'Gargajiya na menu';
@override
String get postMeridiemAbbreviation => r'PM';
@override
String get previousMonthTooltip => r'Watan gabas';
@override
String get previousPageTooltip => r'Wani babban hanya';
@override
String get refreshIndicatorSemanticLabel => r'Nada';
@override
String? get remainingTextFieldCharacterCountFew => null;
@override
String? get remainingTextFieldCharacterCountMany => null;
@override
String get remainingTextFieldCharacterCountOne => r'1 haruffa baki';
@override
String get remainingTextFieldCharacterCountOther => r'$remainingCount haruffa baki';
@override
String? get remainingTextFieldCharacterCountTwo => null;
@override
String get remainingTextFieldCharacterCountZero => r'Ba a nan rubutu sosai';
@override
String get reorderItemDown => r'A sake ƙasa';
@override
String get reorderItemLeft => r'A sake hagu';
@override
String get reorderItemRight => r'A sake dama';
@override
String get reorderItemToEnd => r'A sake zuwa tamu';
@override
String get reorderItemToStart => r'A sake zuwa farko';
@override
String get reorderItemUp => r'A sake sama';
@override
String get rowsPerPageTitle => r'Lambar Fasali:';
@override
ScriptCategory get scriptCategory => ScriptCategory.englishLike;
@override
String get searchFieldLabel => 'Binciken';
@override
String get selectAllButtonLabel => 'DUBA DUK';
@override
String? get selectedRowCountTitleFew => null;
@override
String? get selectedRowCountTitleMany => null;
@override
String get selectedRowCountTitleOne => '1 kaya';
@override
String get selectedRowCountTitleOther => r'$selectedRowCount kayayyaki';
@override
String? get selectedRowCountTitleTwo => null;
@override
String get selectedRowCountTitleZero => 'Babu kaya da aka zabi';
@override
String get showAccountsLabel => 'Nuna Hisobin';
@override
String get showMenuTooltip => 'Nuna Menu';
@override
String get signedInLabel => 'Kasance';
@override
String get tabLabelRaw => r'Tabin $tabIndex daga $tabCount';
@override
TimeOfDayFormat get timeOfDayFormatRaw => TimeOfDayFormat.h_colon_mm_space_a;
@override
String get timePickerHourModeAnnouncement => 'Zaɓi saʼoɗin lokaci';
@override
String get timePickerMinuteModeAnnouncement => 'Zaɓi minti';
@override
String get viewLicensesButtonLabel => 'DUBA LAYINSU';
@override
List<String> get narrowWeekdays => const <String>['L', 'L', 'M', 'K', 'J', 'A', 'A'];
@override
int get firstDayOfWeekIndex => 0;
static const LocalizationsDelegate<MaterialLocalizations> delegate =
_HaMaterialLocalizationsDelegate();
@override
String get calendarModeButtonLabel => 'Canza zuwa kalendar';
@override
String get dateHelpText => 'mm/dd/yyyy';
@override
String get dateInputLabel => 'Shigar Daƙin';
@override
String get dateOutOfRangeLabel => 'A cikin jerin';
@override
String get datePickerHelpText => 'ZAƘA TALATA';
@override
String get dateRangeEndDateSemanticLabelRaw => r'Aikin da ya ƙarshe $fullDate';
@override
String get dateRangeEndLabel => 'Aikin da ya ƙarshe';
@override
String get dateRangePickerHelpText => 'ZAƘA HALIN RANAR';
@override
String get dateRangeStartDateSemanticLabelRaw => 'Aikin da ya gabata \$fullDate';
@override
String get dateRangeStartLabel => 'Aikin da ya gabata';
@override
String get dateSeparator => '/';
@override
String get dialModeButtonLabel => 'Canza zuwa jerin';
@override
String get inputDateModeButtonLabel => 'Canza zuwa shigar';
@override
String get inputTimeModeButtonLabel => 'Canza zuwa jerin bayanin rubutu';
@override
String get invalidDateFormatLabel => 'Tarihin ba daidai ba';
@override
String get invalidDateRangeLabel => 'Siffar saƙo ba tare da hukunci ba';
@override
String get invalidTimeLabel => 'Kasancewa aikin lokaci mai kyau';
@override
String get licensesPackageDetailTextOther => r'$licenseCount layinsu';
@override
String get saveButtonLabel => 'Aji';
@override
String get selectYearSemanticsLabel => 'Zaɓi shekara';
@override
String get timePickerDialHelpText => 'ZAƘA LOKACI';
@override
String get timePickerHourLabel => 'Auren lokaci';
@override
String get timePickerInputHelpText => 'Shigar lokaci';
@override
String get timePickerMinuteLabel => 'Minti';
@override
String get unspecifiedDate => 'Ranar';
@override
String get unspecifiedDateRange => 'Ranar Ayyuka';
@override
String get keyboardKeyAlt => 'Alt';
@override
String get keyboardKeyAltGraph => 'AltGraph';
@override
String get keyboardKeyBackspace => 'BayaRubuta';
@override
String get keyboardKeyCapsLock => 'Caps Lock';
@override
String get keyboardKeyChannelDown => 'BayaKammalaSake';
@override
String get keyboardKeyChannelUp => 'YiKammalaSake';
@override
String get keyboardKeyControl => 'Tsara';
@override
String get keyboardKeyDelete => 'Share';
@override
String get keyboardKeyEject => 'Eject';
@override
String get keyboardKeyEnd => 'Tare';
@override
String get keyboardKeyEscape => 'Goge';
@override
String get keyboardKeyFn => 'Fn';
@override
String get keyboardKeyHome => 'Home';
@override
String get keyboardKeyInsert => 'Shirya';
@override
String get keyboardKeyMeta => 'Meta';
@override
String get keyboardKeyMetaMacOs => 'Amfani da Command';
@override
String get keyboardKeyMetaWindows => 'Windows';
@override
String get keyboardKeyNumLock => 'Num Lock';
@override
String get keyboardKeyNumpad0 => 'Numpad 0';
@override
String get keyboardKeyNumpad1 => 'Numpad 1';
@override
String get keyboardKeyNumpad2 => 'Numpad 2';
@override
String get keyboardKeyNumpad3 => 'Numpad 3';
@override
String get keyboardKeyNumpad4 => 'Numpad 4';
@override
String get keyboardKeyNumpad5 => 'Numpad 5';
@override
String get keyboardKeyNumpad6 => 'Numpad 6';
@override
String get keyboardKeyNumpad7 => 'Numpad 7';
@override
String get keyboardKeyNumpad8 => 'Numpad 8';
@override
String get keyboardKeyNumpad9 => 'Numpad 9';
@override
String get keyboardKeyNumpadAdd => 'Numpad +';
@override
String get keyboardKeyNumpadComma => 'Numpad ,';
@override
String get keyboardKeyNumpadDecimal => 'Numpad .';
@override
String get keyboardKeyNumpadDivide => 'Numpad /';
@override
String get keyboardKeyNumpadEnter => 'Numpad Enter';
@override
String get keyboardKeyNumpadEqual => 'Numpad =';
@override
String get keyboardKeyNumpadMultiply => 'Numpad *';
@override
String get keyboardKeyNumpadParenLeft => 'Numpad (';
@override
String get keyboardKeyNumpadParenRight => 'Numpad )';
@override
String get keyboardKeyNumpadSubtract => 'Numpad -';
@override
String get keyboardKeyPageDown => 'Page Down';
@override
String get keyboardKeyPageUp => 'Page Up';
@override
String get keyboardKeyPower => 'Power';
@override
String get keyboardKeyPowerOff => 'Power Off';
@override
String get keyboardKeyPrintScreen => 'Print Screen';
@override
String get keyboardKeyScrollLock => 'Scroll Lock';
@override
String get keyboardKeySelect => 'Zabi';
@override
String get keyboardKeySpace => 'Space';
}
/// Cupertino Support
/// Strings Copied from "https://github.com/flutter/flutter/blob/master/packages/flutter_localizations/lib/src/l10n/generated_cupertino_localizations.dart"
class _HaCupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
const _HaCupertinoLocalizationsDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'ha';
@override
Future<CupertinoLocalizations> load(Locale locale) async {
final String localeName = intl.Intl.canonicalizedLocale(locale.toString());
// The locale (in this case `ha`) needs to be initialized into the custom =>> `ha`
// date symbols and patterns setup that Flutter uses.
date_symbol_data_custom.initializeDateFormattingCustom(
locale: localeName,
patterns: haLocaleDatePatterns,
symbols: intl.DateSymbols.deserializeFromMap(haDateSymbols),
);
return SynchronousFuture<CupertinoLocalizations>(
HaCupertinoLocalizations(
localeName: localeName,
// The `intl` library's NumberFormat class is generated from CLDR data
// (see https://github.com/dart-lang/intl/blob/master/lib/number_symbols_data.dart).
// Unfortunately, there is no way to use a locale that isn't defined in
// this map and the only way to work around this is to use a listed
// locale's NumberFormat symbols. So, here we use the number formats
// for 'en_US' instead.
decimalFormat: intl.NumberFormat('#,##0.###', 'en_US'),
// DateFormat here will use the symbols and patterns provided in the
// `date_symbol_data_custom.initializeDateFormattingCustom` call above.
// However, an alternative is to simply use a supported locale's
// DateFormat symbols, similar to NumberFormat above.
fullYearFormat: intl.DateFormat('y', localeName),
mediumDateFormat: intl.DateFormat('EEE, MMM d', localeName),
dayFormat: intl.DateFormat('d', localeName),
doubleDigitMinuteFormat: intl.DateFormat('mm', localeName),
singleDigitHourFormat: intl.DateFormat('j', localeName),
singleDigitMinuteFormat: intl.DateFormat.m(localeName),
singleDigitSecondFormat: intl.DateFormat.s(localeName),
),
);
}
@override
bool shouldReload(_HaCupertinoLocalizationsDelegate old) => false;
}
// #enddocregion Delegate
/// A custom set of localizations for the 'nn' locale. In this example, only =>> `ha`
/// the value for openAppDrawerTooltip was modified to use a custom message as
/// an example. Everything else uses the American English (en_US) messages
/// and formatting.
class HaCupertinoLocalizations extends GlobalCupertinoLocalizations {
const HaCupertinoLocalizations({
super.localeName = 'ha',
required super.fullYearFormat,
required super.mediumDateFormat,
required super.decimalFormat,
required super.dayFormat,
required super.singleDigitHourFormat,
required super.singleDigitMinuteFormat,
required super.doubleDigitMinuteFormat,
required super.singleDigitSecondFormat,
});
@override
String get alertDialogLabel => 'Fadakarwa';
@override
String get anteMeridiemAbbreviation => 'AM';
@override
String get copyButtonLabel => 'Kwafa';
@override
String get cutButtonLabel => 'yanke';
@override
String get datePickerDateOrderString => 'mdy';
@override
String get datePickerDateTimeOrderString => 'date_time_dayPeriod';
@override
String? get datePickerHourSemanticsLabelFew => null;
@override
String? get datePickerHourSemanticsLabelMany => null;
@override
String? get datePickerHourSemanticsLabelOne => r"$hour o'clock";
@override
String get datePickerHourSemanticsLabelOther => r"$hour o'clock";
@override
String? get datePickerHourSemanticsLabelTwo => null;
@override
String? get datePickerHourSemanticsLabelZero => null;
@override
String? get datePickerMinuteSemanticsLabelFew => null;
@override
String? get datePickerMinuteSemanticsLabelMany => null;
@override
String? get datePickerMinuteSemanticsLabelOne => '1 minti';
@override
String get datePickerMinuteSemanticsLabelOther => r'$minute minti';
@override
String? get datePickerMinuteSemanticsLabelTwo => null;
@override
String? get datePickerMinuteSemanticsLabelZero => null;
@override
String get modalBarrierDismissLabel => 'Korar';
@override
String get pasteButtonLabel => 'Liƙa';
@override
String get postMeridiemAbbreviation => 'PM';
@override
String get searchTextFieldPlaceholderLabel => 'Bincika';
@override
String get selectAllButtonLabel => 'Zaɓi Duk';
@override
String get tabSemanticsLabelRaw => r'Tab $tabIndex cikin $tabCount';
@override
String? get timerPickerHourLabelFew => null;
@override
String? get timerPickerHourLabelMany => null;
@override
String? get timerPickerHourLabelOne => 'awa';
@override
String get timerPickerHourLabelOther => 'awa';
@override
String? get timerPickerHourLabelTwo => null;
@override
String? get timerPickerHourLabelZero => null;
@override
String? get timerPickerMinuteLabelFew => null;
@override
String? get timerPickerMinuteLabelMany => null;
@override
String? get timerPickerMinuteLabelOne => 'minti.';
@override
String get timerPickerMinuteLabelOther => 'minti.';
@override
String? get timerPickerMinuteLabelTwo => null;
@override
String? get timerPickerMinuteLabelZero => null;
@override
String? get timerPickerSecondLabelFew => null;
@override
String? get timerPickerSecondLabelMany => null;
@override
String? get timerPickerSecondLabelOne => 'dakika.';
@override
String get timerPickerSecondLabelOther => 'dakika.';
@override
String? get timerPickerSecondLabelTwo => null;
@override
String? get timerPickerSecondLabelZero => null;
@override
String get todayLabel => 'Yau';
static const LocalizationsDelegate<CupertinoLocalizations> delegate =
_HaCupertinoLocalizationsDelegate();
}

16
lib/locales/locale.dart Normal file
View file

@ -0,0 +1,16 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/locales/hausa_intl.dart';
import 'package:cake_wallet/locales/yoruba_intl.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
Iterable<LocalizationsDelegate<dynamic>> localizationDelegates = [
S.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
HaMaterialLocalizations.delegate,
HaCupertinoLocalizations.delegate,
YoCupertinoLocalizations.delegate,
YoMaterialLocalizations.delegate,
];

View file

@ -0,0 +1,940 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/date_symbol_data_custom.dart' as date_symbol_data_custom;
import 'package:intl/date_symbols.dart' as intl;
import 'package:intl/intl.dart' as intl;
// #docregion Date
const yoLocaleDatePatterns = {
'd': 'd.',
'E': 'ccc',
'EEEE': 'cccc',
'LLL': 'LLL',
// #enddocregion Date
'LLLL': 'LLLL',
'M': 'L.',
'Md': 'd.M.',
'MEd': 'EEE d.M.',
'MMM': 'LLL',
'MMMd': 'd. MMM',
'MMMEd': 'EEE d. MMM',
'MMMM': 'LLLL',
'MMMMd': 'd. MMMM',
'MMMMEEEEd': 'EEEE d. MMMM',
'QQQ': 'QQQ',
'QQQQ': 'QQQQ',
'y': 'y',
'yM': 'M.y',
'yMd': 'd.M.y',
'yMEd': 'EEE d.MM.y',
'yMMM': 'MMM y',
'yMMMd': 'd. MMM y',
'yMMMEd': 'EEE d. MMM y',
'yMMMM': 'MMMM y',
'yMMMMd': 'd. MMMM y',
'yMMMMEEEEd': 'EEEE d. MMMM y',
'yQQQ': 'QQQ y',
'yQQQQ': 'QQQQ y',
'H': 'HH',
'Hm': 'HH:mm',
'Hms': 'HH:mm:ss',
'j': 'HH',
'jm': 'HH:mm',
'jms': 'HH:mm:ss',
'jmv': 'HH:mm v',
'jmz': 'HH:mm z',
'jz': 'HH z',
'm': 'm',
'ms': 'mm:ss',
's': 's',
'v': 'v',
'z': 'z',
'zzzz': 'zzzz',
'ZZZZ': 'ZZZZ',
};
// #docregion Date2
const yoDateSymbols = {
'NAME': 'yo',
'ERAS': <dynamic>[
'f.Sk.',
'e.Lk.',
],
// #enddocregion Date2
'ERANAMES': <dynamic>[
'Ṣaaju Kristi',
'Lẹhin Kristi',
],
'NARROWMONTHS': <dynamic>[
'J',
'F',
'M',
'A',
'M',
'J',
'J',
'A',
'S',
'O',
'N',
'D',
],
'STANDALONENARROWMONTHS': <dynamic>[
'J',
'F',
'M',
'A',
'M',
'J',
'J',
'A',
'S',
'O',
'N',
'D',
],
'MONTHS': <dynamic>[
'januárì',
'feburárì',
'màársì',
'éfrílù',
'méè',
'júùnù',
'júùlù',
'ágústà',
'sètẹ̀mbà',
'ọkùtọ̀bà',
'nọvẹ̀mbà',
'dẹsẹ̀mbà',
],
'STANDALONEMONTHS': <dynamic>[
'januárì',
'feburárì',
'màársì',
'éfrílù',
'méè',
'júùnù',
'júùlù',
'ágústà',
'sètẹ̀mbà',
'ọkùtọ̀bà',
'nọvẹ̀mbà',
'dẹsẹ̀mbà',
],
'SHORTMONTHS': <dynamic>[
'jan.',
'feb.',
'mar.',
'ápr.',
'mẹ̀',
'jún.',
'júl.',
'ágú.',
'sẹ̀p.',
'ọkù.',
'nọv.',
'dẹs.',
],
'STANDALONESHORTMONTHS': <dynamic>[
'jan',
'feb',
'mar',
'ápr',
'mẹ̀',
'jún',
'júl',
'ágú',
'sẹ̀p',
'ọkù',
'nọv',
'dẹs',
],
'WEEKDAYS': <dynamic>[
'ọjọ́ Ajé',
'ọjọ́ Ìsẹ́gun',
'ọjọ́ Ìsẹ́gun-Etì',
'ọjọ́ Ìsẹ́gun-Ọ̀rú',
'ọjọ́ Àìkú',
'ọjọ́ Jíń',
'ọjọ́ Àbámẹ́ta',
],
'STANDALONEWEEKDAYS': <dynamic>[
'Ọjọ́ Ajé',
'Ọjọ́ Ìsẹ́gun',
'Ọjọ́ Ìsẹ́gun-Ẹtì',
'Ọjọ́ Ìsẹ́gun-Ọ̀rú',
'Ọjọ́ Àìkú',
'Ọjọ́ Jímọ̀',
'Ọjọ́ Àbámẹ́ta',
],
'SHORTWEEKDAYS': <dynamic>[
'Ajé',
'Ìsẹ́gun',
'Ìsẹ́gun-Ẹtì',
'Ìsẹ́gun-Ọ̀rú',
'Àìkú',
'Jímọ̀',
'Àbámẹ́ta',
],
'STANDALONESHORTWEEKDAYS': <dynamic>[
'Ajé',
'Ìsẹ́gun',
'Ìsẹ́gun-Ẹtì',
'Ìsẹ́gun-Ọ̀rú',
'Àìkú',
'Jímọ̀',
'Àbámẹ́ta',
],
'NARROWWEEKDAYS': <dynamic>[
'A',
'A',
'Ì',
'A',
'À',
'J',
'À',
],
'STANDALONENARROWWEEKDAYS': <dynamic>[
'A',
'A',
'Ì',
'A',
'À',
'J',
'À',
],
'SHORTQUARTERS': <dynamic>[
'K1',
'K2',
'K3',
'K4',
],
'QUARTERS': <dynamic>[
'1. kwata',
'2. kwata',
'3. kwata',
'4. kwata',
],
'AMPMS': <dynamic>[
'a.m.',
'p.m.',
],
'DATEFORMATS': <dynamic>[
'EEEE d. MMMM y',
'd. MMMM y',
'd. MMM y',
'dd.MM.y',
],
'TIMEFORMATS': <dynamic>[
'HH:mm:ss zzzz',
'HH:mm:ss z',
'HH:mm:ss',
'HH:mm',
],
'AVAILABLEFORMATS': null,
'FIRSTDAYOFWEEK': 0,
'WEEKENDRANGE': <dynamic>[
5,
6,
],
'FIRSTWEEKCUTOFFDAY': 3,
'DATETIMEFORMATS': <dynamic>[
'{1} {0}',
'{1} \'kl\'. {0}',
'{1}, {0}',
'{1}, {0}',
],
};
// #docregion Delegate
class _YoMaterialLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
const _YoMaterialLocalizationsDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'yo';
@override
Future<MaterialLocalizations> load(Locale locale) async {
final String localeName = intl.Intl.canonicalizedLocale(locale.toString());
// The locale (in this case `yo`) needs to be initialized into the custom
// date symbols and patterns setup that Flutter uses.
date_symbol_data_custom.initializeDateFormattingCustom(
locale: localeName,
patterns: yoLocaleDatePatterns,
symbols: intl.DateSymbols.deserializeFromMap(yoDateSymbols),
);
return SynchronousFuture<MaterialLocalizations>(
YoMaterialLocalizations(
localeName: localeName,
// The `intl` library's NumberFormat class is generated from CLDR data
// (see https://github.com/dart-lang/intl/blob/master/lib/number_symbols_data.dart).
// Unfortunately, there is no way to use a locale that isn't defined in
// this map and the only way to work around this is to use a listed
// locale's NumberFormat symbols. So, here we use the number formats
// for 'en_US' instead.
decimalFormat: intl.NumberFormat('#,##0.###', 'en_US'),
twoDigitZeroPaddedFormat: intl.NumberFormat('00', 'en_US'),
// DateFormat here will use the symbols and patterns provided in the
// `date_symbol_data_custom.initializeDateFormattingCustom` call above.
// However, an alternative is to simply use a supported locale's
// DateFormat symbols, similar to NumberFormat above.
fullYearFormat: intl.DateFormat('y', localeName),
compactDateFormat: intl.DateFormat('yMd', localeName),
shortDateFormat: intl.DateFormat('yMMMd', localeName),
mediumDateFormat: intl.DateFormat('EEE, MMM d', localeName),
longDateFormat: intl.DateFormat('EEEE, MMMM d, y', localeName),
yearMonthFormat: intl.DateFormat('MMMM y', localeName),
shortMonthDayFormat: intl.DateFormat('MMM d', localeName),
),
);
}
@override
bool shouldReload(_YoMaterialLocalizationsDelegate old) => false;
}
// #enddocregion Delegate
class YoMaterialLocalizations extends GlobalMaterialLocalizations {
const YoMaterialLocalizations({
super.localeName = 'yo',
required super.fullYearFormat,
required super.compactDateFormat,
required super.shortDateFormat,
required super.mediumDateFormat,
required super.longDateFormat,
required super.yearMonthFormat,
required super.shortMonthDayFormat,
required super.decimalFormat,
required super.twoDigitZeroPaddedFormat,
});
// #docregion Getters
@override
String get moreButtonTooltip => r'Kò sí ìròhùn tí ó múni';
@override
String get aboutListTileTitleRaw => r'Fun Àpótí àwọn $applicationname';
@override
String get alertDialogLabel => r'Ìròhùn Àlàyé';
// #enddocregion Getters
@override
String get anteMeridiemAbbreviation => r'AM';
@override
String get backButtonTooltip => r'Fíran';
@override
String get cancelButtonLabel => r'FAGILE';
@override
String get closeButtonLabel => r'KÚ';
@override
String get closeButtonTooltip => r'Kú';
@override
String get collapsedIconTapHint => r'Tá';
@override
String get continueButtonLabel => r'TÓ WÁ';
@override
String get copyButtonLabel => r'DÚPLÍKÉTÍ';
@override
String get cutButtonLabel => r'TÒ';
@override
String get deleteButtonTooltip => r'Máa kú';
@override
String get dialogLabel => r'Ìròhùn';
@override
String get drawerLabel => r'Àgbèjọ àwọn àpọ̀tí';
@override
String get expandedIconTapHint => r'Tá';
@override
String get firstPageTooltip => r'Ojú ewe';
@override
String get hideAccountsLabel => r'Fí èrò àpótí wáyé sílẹ̀';
@override
String get lastPageTooltip => r'Ojú ayé';
@override
String get licensesPageTitle => r'Ìròhùn Ọdún';
@override
String get modalBarrierDismissLabel => r'Sọ';
@override
String get nextMonthTooltip => r'Oṣù kọja';
@override
String get nextPageTooltip => r'Ojú ọjọ́ kẹta';
@override
String get okButtonLabel => r'Ò daájú';
@override
// A custom drawer tooltip message.
String get openAppDrawerTooltip => r'Aya ntọju Iwe Awọn Aka';
// #docregion Raw
@override
String get pageRowsInfoTitleRaw => r'$firstRow$lastRow lati $rowCount';
@override
String get pageRowsInfoTitleApproximateRaw => r'$firstRow$lastRow lati kiakia $rowCount';
// #enddocregion Raw
@override
String get pasteButtonLabel => r'TÌ';
@override
String get popupMenuLabel => r'Meniu Pop-up';
@override
String get menuBarMenuLabel => r'Meniu Akọkọ';
@override
String get postMeridiemAbbreviation => r'PM';
@override
String get previousMonthTooltip => r'Oṣu Kanakana';
@override
String get previousPageTooltip => r'Ojú ewé akọkọ kan';
@override
String get refreshIndicatorSemanticLabel => r'Gbiyanju';
@override
String? get remainingTextFieldCharacterCountFew => null;
@override
String? get remainingTextFieldCharacterCountMany => null;
@override
String get remainingTextFieldCharacterCountOne => r'1 àmì báálẹ̀';
@override
String get remainingTextFieldCharacterCountOther => r'$remainingCount àmì báálẹ̀';
@override
String? get remainingTextFieldCharacterCountTwo => null;
@override
String get remainingTextFieldCharacterCountZero => r'Kò sí ìwọlé létà láti ń ṣe';
@override
String get reorderItemDown => r'Jù sí ilẹ';
@override
String get reorderItemLeft => r'Jù sí àrà';
@override
String get reorderItemRight => r'Jù sí òtútù';
@override
String get reorderItemToEnd => r'Jù sí ìbẹ̀jì';
@override
String get reorderItemToStart => r'Jù sí àkọ́kọ́';
@override
String get reorderItemUp => r'Jù sí ọ̀rùn';
@override
String get rowsPerPageTitle => r'Ìlò Fún àwọn Ìtọ́kasíwájú:';
@override
ScriptCategory get scriptCategory => ScriptCategory.englishLike;
@override
String get searchFieldLabel => 'Ṣẹda';
@override
String get selectAllButtonLabel => 'FADỌHỌN DỌFÚN GBÁJÚMỌ̀';
@override
String? get selectedRowCountTitleFew => null;
@override
String? get selectedRowCountTitleMany => null;
@override
String get selectedRowCountTitleOne => '1 káyé';
@override
String get selectedRowCountTitleOther => r'$selectedRowCount káyé';
@override
String? get selectedRowCountTitleTwo => null;
@override
String get selectedRowCountTitleZero => 'Kò sí káyé ti o wọlé';
@override
String get showAccountsLabel => 'Fi iyipada mu kọ';
@override
String get showMenuTooltip => 'Fi Meniu mu kọ';
@override
String get signedInLabel => 'Ọ̀nà';
@override
String get tabLabelRaw => r'Àwọn tabin $tabIndex lati $tabCount';
@override
TimeOfDayFormat get timeOfDayFormatRaw => TimeOfDayFormat.h_colon_mm_space_a;
@override
String get timePickerHourModeAnnouncement => 'Tuntun waqtu lọ';
@override
String get timePickerMinuteModeAnnouncement => 'Tuntun daɗi minti';
@override
String get viewLicensesButtonLabel => 'WO NIKI';
@override
List<String> get narrowWeekdays => const <String>['L', 'L', 'A', 'O', '', '', ''];
@override
int get firstDayOfWeekIndex => 0;
static const LocalizationsDelegate<MaterialLocalizations> delegate =
_YoMaterialLocalizationsDelegate();
@override
String get calendarModeButtonLabel => 'Tọ́rọ̀ kálẹ̀ndà';
@override
String get dateHelpText => 'mm/dd/yyyy';
@override
String get dateInputLabel => 'Firanṣẹ̀ Ọjọ́';
@override
String get dateOutOfRangeLabel => 'Nínú iwọ̀ lọ́wọ́';
@override
String get datePickerHelpText => 'WÁSÍ';
@override
String get dateRangeEndDateSemanticLabelRaw => r'Ọjọ́ tuntun to ṣà';
@override
String get dateRangeEndLabel => 'Ọjọ́ tuntun to ṣà';
@override
String get dateRangePickerHelpText => 'WÁSÍ ÌGBÀ';
@override
String get dateRangeStartDateSemanticLabelRaw => 'Ọjọ́ tuntun ti dá';
@override
String get dateRangeStartLabel => 'Ọjọ́ tuntun ti dá';
@override
String get dateSeparator => '/';
@override
String get dialModeButtonLabel => 'Tọ́rọ̀ wakati';
@override
String get inputDateModeButtonLabel => 'Tọ́rọ̀ firanṣẹ̀ ọjọ́';
@override
String get inputTimeModeButtonLabel => 'Tọ́rọ̀ wakati bayi lọ́wọ́';
@override
String get invalidDateFormatLabel => 'Akọ́kọ́tọ́ tó jẹ́kúnrin';
@override
String get invalidDateRangeLabel => 'Àmì jẹ́ káàkiri lẹ́yìn ilé';
@override
String get invalidTimeLabel => 'Akọ́kọ́tọ́ àkójọ ìwádìí';
@override
String get licensesPackageDetailTextOther => r'$licenseCount àwọn níkí';
@override
String get saveButtonLabel => 'TÙN DÁRA';
@override
String get selectYearSemanticsLabel => 'Fọ́ọ̀ shẹ́kàrà';
@override
String get timePickerDialHelpText => 'WÁSÍ WÁKÀTÌ';
@override
String get timePickerHourLabel => 'Wákàtì àṣà';
@override
String get timePickerInputHelpText => 'Shìgárà wákàtì';
@override
String get timePickerMinuteLabel => 'Mìntì';
@override
String get unspecifiedDate => 'Ọjọ̀kúnrin';
@override
String get unspecifiedDateRange => 'Ọjọ̀kúnrin àdáyọ̀';
@override
String get keyboardKeyAlt => 'Alt';
@override
String get keyboardKeyAltGraph => 'AltGraph';
@override
String get keyboardKeyBackspace => 'Báckspàcè';
@override
String get keyboardKeyCapsLock => 'Caps Lock';
@override
String get keyboardKeyChannelDown => 'Báyàkàmmàlàsàké';
@override
String get keyboardKeyChannelUp => 'Yíkàmmàlàsàké';
@override
String get keyboardKeyControl => 'Kọ́ntírọ̀l';
@override
String get keyboardKeyDelete => 'Shápè';
@override
String get keyboardKeyEject => 'Èjẹ̀tì';
@override
String get keyboardKeyEnd => 'Tàbí';
@override
String get keyboardKeyEscape => 'Tòkè';
@override
String get keyboardKeyFn => 'Fn';
@override
String get keyboardKeyHome => 'Ile';
@override
String get keyboardKeyInsert => 'Fi sori';
@override
String get keyboardKeyMeta => 'Meta';
@override
String get keyboardKeyMetaMacOs => 'Amfani pẹlu Command';
@override
String get keyboardKeyMetaWindows => 'Windows';
@override
String get keyboardKeyNumLock => 'Num Lock';
@override
String get keyboardKeyNumpad0 => 'Numpad 0';
@override
String get keyboardKeyNumpad1 => 'Numpad 1';
@override
String get keyboardKeyNumpad2 => 'Numpad 2';
@override
String get keyboardKeyNumpad3 => 'Numpad 3';
@override
String get keyboardKeyNumpad4 => 'Numpad 4';
@override
String get keyboardKeyNumpad5 => 'Numpad 5';
@override
String get keyboardKeyNumpad6 => 'Numpad 6';
@override
String get keyboardKeyNumpad7 => 'Numpad 7';
@override
String get keyboardKeyNumpad8 => 'Numpad 8';
@override
String get keyboardKeyNumpad9 => 'Numpad 9';
@override
String get keyboardKeyNumpadAdd => 'Numpad +';
@override
String get keyboardKeyNumpadComma => 'Numpad ,';
@override
String get keyboardKeyNumpadDecimal => 'Numpad .';
@override
String get keyboardKeyNumpadDivide => 'Numpad /';
@override
String get keyboardKeyNumpadEnter => 'Numpad Enter';
@override
String get keyboardKeyNumpadEqual => 'Numpad =';
@override
String get keyboardKeyNumpadMultiply => 'Numpad *';
@override
String get keyboardKeyNumpadParenLeft => 'Numpad (';
@override
String get keyboardKeyNumpadParenRight => 'Numpad )';
@override
String get keyboardKeyNumpadSubtract => 'Numpad -';
@override
String get keyboardKeyPageDown => 'Page Down';
@override
String get keyboardKeyPageUp => 'Page Up';
@override
String get keyboardKeyPower => 'Power';
@override
String get keyboardKeyPowerOff => 'Power Off';
@override
String get keyboardKeyPrintScreen => 'Print Screen';
@override
String get keyboardKeyScrollLock => 'Scroll Lock';
@override
String get keyboardKeySelect => 'Zabi';
@override
String get keyboardKeySpace => 'Space';
}
/// Cupertino Support
/// Strings Copied from "https://github.com/flutter/flutter/blob/master/packages/flutter_localizations/lib/src/l10n/generated_cupertino_localizations.dart"
class _YoCupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
const _YoCupertinoLocalizationsDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'yo';
@override
Future<CupertinoLocalizations> load(Locale locale) async {
final String localeName = intl.Intl.canonicalizedLocale(locale.toString());
// The locale (in this case `yo`) needs to be initialized into the custom =>> `yo`
// date symbols and patterns setup that Flutter uses.
date_symbol_data_custom.initializeDateFormattingCustom(
locale: localeName,
patterns: yoLocaleDatePatterns,
symbols: intl.DateSymbols.deserializeFromMap(yoDateSymbols),
);
return SynchronousFuture<CupertinoLocalizations>(
YoCupertinoLocalizations(
localeName: localeName,
// The `intl` library's NumberFormat class is generated from CLDR data
// (see https://github.com/dart-lang/intl/blob/master/lib/number_symbols_data.dart).
// Unfortunately, there is no way to use a locale that isn't defined in
// this map and the only way to work around this is to use a listed
// locale's NumberFormat symbols. So, here we use the number formats
// for 'en_US' instead.
decimalFormat: intl.NumberFormat('#,##0.###', 'en_US'),
// DateFormat here will use the symbols and patterns provided in the
// `date_symbol_data_custom.initializeDateFormattingCustom` call above.
// However, an alternative is to simply use a supported locale's
// DateFormat symbols, similar to NumberFormat above.
fullYearFormat: intl.DateFormat('y', localeName),
mediumDateFormat: intl.DateFormat('EEE, MMM d', localeName),
dayFormat: intl.DateFormat('d', localeName),
doubleDigitMinuteFormat: intl.DateFormat('mm', localeName),
singleDigitHourFormat: intl.DateFormat('j', localeName),
singleDigitMinuteFormat: intl.DateFormat.m(localeName),
singleDigitSecondFormat: intl.DateFormat.s(localeName),
),
);
}
@override
bool shouldReload(_YoCupertinoLocalizationsDelegate old) => false;
}
// #enddocregion Delegate
/// A custom set of localizations for the 'nn' locale. In this example, only =>> `yo`
/// the value for openAppDrawerTooltip was modified to use a custom message as
/// an example. Everything else uses the American English (en_US) messages
/// and formatting.
class YoCupertinoLocalizations extends GlobalCupertinoLocalizations {
const YoCupertinoLocalizations({
super.localeName = 'yo',
required super.fullYearFormat,
required super.mediumDateFormat,
required super.decimalFormat,
required super.dayFormat,
required super.singleDigitHourFormat,
required super.singleDigitMinuteFormat,
required super.doubleDigitMinuteFormat,
required super.singleDigitSecondFormat,
});
@override
String get alertDialogLabel => 'Àdàkárò';
@override
String get anteMeridiemAbbreviation => 'AM';
@override
String get copyButtonLabel => 'Kòpy';
@override
String get cutButtonLabel => 'Kọ́t';
@override
String get datePickerDateOrderString => 'mdy';
@override
String get datePickerDateTimeOrderString => 'date_time_dayPeriod';
@override
String? get datePickerHourSemanticsLabelFew => null;
@override
String? get datePickerHourSemanticsLabelMany => null;
@override
String? get datePickerHourSemanticsLabelOne => r"$hour o'clock";
@override
String get datePickerHourSemanticsLabelOther => r"$hour o'clock";
@override
String? get datePickerHourSemanticsLabelTwo => null;
@override
String? get datePickerHourSemanticsLabelZero => null;
@override
String? get datePickerMinuteSemanticsLabelFew => null;
@override
String? get datePickerMinuteSemanticsLabelMany => null;
@override
String? get datePickerMinuteSemanticsLabelOne => '1 wakati';
@override
String get datePickerMinuteSemanticsLabelOther => r'$minute wakati';
@override
String? get datePickerMinuteSemanticsLabelTwo => null;
@override
String? get datePickerMinuteSemanticsLabelZero => null;
@override
String get modalBarrierDismissLabel => 'Búta';
@override
String get pasteButtonLabel => 'Tẹ́ẹ́';
@override
String get postMeridiemAbbreviation => 'PM';
@override
String get searchTextFieldPlaceholderLabel => 'Wúró àtúntà';
@override
String get selectAllButtonLabel => 'Fírànsé gbógbo';
@override
String get tabSemanticsLabelRaw => r'Tab $tabIndex nínú $tabCount';
@override
String? get timerPickerHourLabelFew => null;
@override
String? get timerPickerHourLabelMany => null;
@override
String? get timerPickerHourLabelOne => 'òǹdì';
@override
String get timerPickerHourLabelOther => 'òǹdì';
@override
String? get timerPickerHourLabelTwo => null;
@override
String? get timerPickerHourLabelZero => null;
@override
String? get timerPickerMinuteLabelFew => null;
@override
String? get timerPickerMinuteLabelMany => null;
@override
String? get timerPickerMinuteLabelOne => 'wakati.';
@override
String get timerPickerMinuteLabelOther => 'wakati.';
@override
String? get timerPickerMinuteLabelTwo => null;
@override
String? get timerPickerMinuteLabelZero => null;
@override
String? get timerPickerSecondLabelFew => null;
@override
String? get timerPickerSecondLabelMany => null;
@override
String? get timerPickerSecondLabelOne => 'dákìkà.';
@override
String get timerPickerSecondLabelOther => 'dákìkà.';
@override
String? get timerPickerSecondLabelTwo => null;
@override
String? get timerPickerSecondLabelZero => null;
@override
String get todayLabel => 'Oyọ';
static const LocalizationsDelegate<CupertinoLocalizations> delegate =
_YoCupertinoLocalizationsDelegate();
}

View file

@ -3,6 +3,7 @@ import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/language_service.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/locales/locale.dart';
import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cw_core/root_dir.dart';
@ -13,7 +14,6 @@ import 'package:hive/hive.dart';
import 'package:cake_wallet/di.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/theme_base.dart';
@ -44,7 +44,6 @@ final rootKey = GlobalKey<RootState>();
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
Future<void> main() async {
await runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
@ -107,32 +106,27 @@ Future<void> main() async {
}
final secureStorage = secureStorageShared;
final transactionDescriptionsBoxKey = await getEncryptionKey(
secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
final tradesBoxKey = await getEncryptionKey(
secureStorage: secureStorage, forKey: Trade.boxKey);
final ordersBoxKey = await getEncryptionKey(
secureStorage: secureStorage, forKey: Order.boxKey);
final transactionDescriptionsBoxKey =
await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
final ordersBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Order.boxKey);
final contacts = await Hive.openBox<Contact>(Contact.boxName);
final nodes = await Hive.openBox<Node>(Node.boxName);
final transactionDescriptions = await Hive.openBox<TransactionDescription>(
TransactionDescription.boxName,
encryptionKey: transactionDescriptionsBoxKey);
final trades =
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
final orders =
await Hive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
final trades = await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
final orders = await Hive.openBox<Order>(Order.boxName, encryptionKey: ordersBoxKey);
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
final templates = await Hive.openBox<Template>(Template.boxName);
final exchangeTemplates =
await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
final exchangeTemplates = await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
final anonpayInvoiceInfo = await Hive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
Box<UnspentCoinsInfo>? unspentCoinsInfoSource;
if (!isMoneroOnly) {
unspentCoinsInfoSource = await Hive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
}
await initialSetup(
sharedPreferences: await SharedPreferences.getInstance(),
nodes: nodes,
@ -188,8 +182,7 @@ Future<void> initialSetup(
transactionDescriptionBox: transactionDescriptions,
ordersSource: ordersSource,
anonpayInvoiceInfoSource: anonpayInvoiceInfo,
unspentCoinsInfoSource: unspentCoinsInfoSource,
);
unspentCoinsInfoSource: unspentCoinsInfoSource);
await bootstrap(navigatorKey);
monero?.onStartup();
}
@ -200,8 +193,7 @@ class App extends StatefulWidget {
}
class AppState extends State<App> with SingleTickerProviderStateMixin {
AppState()
: yatStore = getIt.get<YatStore>() {
AppState() : yatStore = getIt.get<YatStore>() {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
}
@ -267,17 +259,14 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
final settingsStore = appStore.settingsStore;
final statusBarColor = Colors.transparent;
final authenticationStore = getIt.get<AuthenticationStore>();
final initialRoute =
authenticationStore.state == AuthenticationState.uninitialized
final initialRoute = authenticationStore.state == AuthenticationState.uninitialized
? Routes.disclaimer
: Routes.login;
final currentTheme = settingsStore.currentTheme;
final statusBarBrightness = currentTheme.type == ThemeType.dark
? Brightness.light
: Brightness.dark;
final statusBarIconBrightness = currentTheme.type == ThemeType.dark
? Brightness.light
: Brightness.dark;
final statusBarBrightness =
currentTheme.type == ThemeType.dark ? Brightness.light : Brightness.dark;
final statusBarIconBrightness =
currentTheme.type == ThemeType.dark ? Brightness.light : Brightness.dark;
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: statusBarColor,
statusBarBrightness: statusBarBrightness,
@ -294,12 +283,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
navigatorKey: navigatorKey,
debugShowCheckedModeBanner: false,
theme: settingsStore.theme,
localizationsDelegates: [
S.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
localizationsDelegates: localizationDelegates,
supportedLocales: S.delegate.supportedLocales,
locale: Locale(settingsStore.languageCode),
onGenerateRoute: (settings) => Router.createRoute(settings),

View file

@ -10,7 +10,7 @@ class CWMoneroAccountList extends MoneroAccountList {
final moneroWallet = _wallet as MoneroWallet;
final accounts = moneroWallet.walletAddresses.accountList
.accounts
.map((acc) => Account(id: acc.id, label: acc.label))
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
.toList();
return ObservableList<Account>.of(accounts);
}
@ -32,7 +32,7 @@ class CWMoneroAccountList extends MoneroAccountList {
final moneroWallet = wallet as MoneroWallet;
return moneroWallet.walletAddresses.accountList
.getAll()
.map((acc) => Account(id: acc.id, label: acc.label))
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
.toList();
}
@ -122,7 +122,7 @@ class CWMoneroWalletDetails extends MoneroWalletDetails {
Account get account {
final moneroWallet = _wallet as MoneroWallet;
final acc = moneroWallet.walletAddresses.account;
return Account(id: acc!.id, label: acc.label);
return Account(id: acc!.id, label: acc.label, balance: acc.balance);
}
@computed
@ -316,13 +316,13 @@ class CWMonero extends Monero {
Account getCurrentAccount(Object wallet) {
final moneroWallet = wallet as MoneroWallet;
final acc = moneroWallet.walletAddresses.account;
return Account(id: acc!.id, label: acc.label);
return Account(id: acc!.id, label: acc.label, balance: acc.balance);
}
@override
void setCurrentAccount(Object wallet, int id, String label) {
void setCurrentAccount(Object wallet, int id, String label, String? balance) {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label, balance: balance);
}
@override

View file

@ -1,7 +1,9 @@
import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
import 'package:cake_wallet/core/totp_request_details.dart';
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/qr_view_data.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
@ -9,6 +11,7 @@ import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/onramper_page.dart';
import 'package:cake_wallet/src/screens/buy/payfura_page.dart';
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart';
@ -31,6 +34,10 @@ import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart';
import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_qr_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
import 'package:cake_wallet/src/screens/support/support_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
@ -41,15 +48,14 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/utils/language_list.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart';
import 'package:cake_wallet/exchange/trade.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/wallet_type.dart';
@ -63,9 +69,6 @@ import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
import 'package:cake_wallet/src/screens/restore/restore_options_page.dart';
import 'package:cake_wallet/src/screens/restore/restore_wallet_options_page.dart';
import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_page.dart';
import 'package:cake_wallet/src/screens/restore/restore_wallet_from_keys_page.dart';
import 'package:cake_wallet/src/screens/send/send_page.dart';
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
import 'package:cake_wallet/src/screens/seed_language/seed_language_page.dart';
@ -151,14 +154,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>(param1: callback));
case Routes.moneroRestoreWalletFromWelcome:
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>(
param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
Navigator.pushNamed(
context.context, Routes.restoreWallet, arguments: WalletType.monero)),
fullscreenDialog: true);
case Routes.restoreWalletType:
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<NewWalletTypePage>(
@ -172,71 +167,57 @@ Route<dynamic> createRoute(RouteSettings settings) {
return createRoute(RouteSettings(name: Routes.restoreWalletType));
}
final isNewInstall = settings.arguments as bool;
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<RestoreOptionsPage>());
fullscreenDialog: true,
builder: (_) => getIt.get<RestoreOptionsPage>(param1: isNewInstall));
case Routes.restoreWalletOptions:
final type = WalletType.monero; //settings.arguments as WalletType;
case Routes.restoreWalletFromSeedKeys:
final isNewInstall = settings.arguments as bool;
return CupertinoPageRoute<void>(
builder: (_) => RestoreWalletOptionsPage(
type: type,
onRestoreFromSeed: (context) {
final route = type == WalletType.monero
? Routes.seedLanguage
: Routes.restoreWalletFromSeed;
final args = type == WalletType.monero
? [type, Routes.restoreWalletFromSeed]
: [type];
if (isNewInstall) {
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>(
param1: (PinCodeState<PinCodeWidget> context, dynamic _) {
if (isSingleCoin) {
return Navigator.of(context.context)
.pushNamed(Routes.restoreWallet, arguments: availableWalletTypes.first);
}
Navigator.of(context).pushNamed(route, arguments: args);
},
onRestoreFromKeys: (context) {
final route = type == WalletType.monero
? Routes.seedLanguage
: Routes.restoreWalletFromKeys;
final args = type == WalletType.monero
? [type, Routes.restoreWalletFromKeys]
: [type];
Navigator.of(context).pushNamed(route, arguments: args);
}));
case Routes.restoreWalletOptionsFromWelcome:
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<SetupPinCodePage>(
param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
Navigator.pushNamed(
context.context, Routes.restoreWalletType)),
fullscreenDialog: true);
return Navigator.pushNamed(
context.context, Routes.restoreWalletType);
}),
fullscreenDialog: true);
} else if (isSingleCoin) {
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<WalletRestorePage>(
param1: availableWalletTypes.first
));
} else {
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<NewWalletTypePage>(
param1: (BuildContext context, WalletType type) =>
Navigator.of(context)
.pushNamed(Routes.restoreWallet, arguments: type),
param2: false));
}
case Routes.seed:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) =>
getIt.get<WalletSeedPage>(param1: settings.arguments as bool));
case Routes.restoreWallet:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<WalletRestorePage>(
param1: settings.arguments as WalletType));
case Routes.restoreWalletFromSeed:
final type = settings.arguments as WalletType;
case Routes.sweepingWalletPage:
return CupertinoPageRoute<void>(
builder: (_) => RestoreWalletFromSeedPage(type: type));
case Routes.restoreWalletFromKeys:
final args = settings.arguments as List<dynamic>;
final type = args.first as WalletType;
final language =
type == WalletType.monero ? args[1] as String : LanguageList.english;
final walletRestorationFromKeysVM =
getIt.get<WalletRestorationFromKeysVM>(param1: [type, language]);
return CupertinoPageRoute<void>(
builder: (_) => RestoreWalletFromKeysPage(
walletRestorationFromKeysVM: walletRestorationFromKeysVM));
builder: (_) => getIt.get<SweepingWalletPage>());
case Routes.dashboard:
return CupertinoPageRoute<void>(
@ -257,7 +238,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.receive:
return CupertinoPageRoute<void>(
fullscreenDialog: true, builder: (_) => getIt.get<ReceivePage>());
builder: (_) => getIt.get<ReceivePage>());
case Routes.addressPage:
return CupertinoPageRoute<void>(
@ -299,7 +280,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.auth:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_)
builder: (_)
=> SettingsStoreBase.walletPasswordDirectInput
? getIt.get<WalletUnlockPage>(
param1: WalletUnlockArguments(
@ -310,10 +291,19 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: settings.arguments as OnAuthenticationFinished,
param2: true));
case Routes.totpAuthCodePage:
final args = settings.arguments as TotpAuthArgumentsModel;
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<TotpAuthCodePage>(
param1: args,
),
);
case Routes.walletUnlockLoadable:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_)
builder: (_)
=> getIt.get<WalletUnlockPage>(
param1: settings.arguments as WalletUnlockArguments,
instanceName: 'wallet_unlock_loadable',
@ -414,6 +404,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.tradeDetails:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) =>
getIt.get<TradeDetailsPage>(param1: settings.arguments as Trade));
@ -431,6 +422,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
final args = settings.arguments as List;
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_) =>
getIt.get<BuyWebViewPage>(param1: args));
@ -440,6 +432,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
getIt.get<WalletRestorationFromSeedVM>(param1: args);
return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => RestoreWalletFromSeedDetailsPage(
walletRestorationFromSeedVM: walletRestorationFromSeedVM));
@ -473,6 +466,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.restoreFromBackup:
return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<RestoreFromBackupPage>());
case Routes.support:
@ -493,14 +487,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: args));
case Routes.fullscreenQR:
final args = settings.arguments as Map<String, dynamic>;
return MaterialPageRoute<void>(
builder: (_) =>
getIt.get<FullscreenQRPage>(
param1: args['qrData'] as String,
param2: args['version'] as int?,
param1: settings.arguments as QrViewData,
));
case Routes.ioniaWelcomePage:
@ -583,7 +573,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.anonPayInvoicePage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(builder: (_) => getIt.get<AnonPayInvoicePage>(param1: args));
return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<AnonPayInvoicePage>(param1: args));
case Routes.anonPayReceivePage:
final anonInvoiceViewData = settings.arguments as AnonpayInfoBase;
@ -598,6 +590,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
opaque: false,
pageBuilder: (_, __, ___) => DesktopDashboardActions(getIt<DashboardViewModel>()),
);
case Routes.desktop_settings_page:
return CupertinoPageRoute<void>(
builder: (_) => DesktopSettingsPage());
@ -605,11 +598,22 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.empty_no_route:
return MaterialPageRoute<void>(
builder: (_) => SizedBox.shrink());
case Routes.transactionsPage:
return CupertinoPageRoute<void>(
settings: settings,
fullscreenDialog: true,
builder: (_) => getIt.get<TransactionsPage>());
case Routes.setup_2faPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<Setup2FAPage>());
case Routes.setup_2faQRPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<Setup2FAQRPage>());
case Routes.modify2FAPage:
return MaterialPageRoute<void>(builder: (_) => getIt.get<Modify2FAPage>());
default:
return MaterialPageRoute<void>(
builder: (_) => Scaffold(

View file

@ -3,14 +3,9 @@ class Routes {
static const newWallet = '/new_wallet';
static const setupPin = '/setup_pin_code';
static const newWalletFromWelcome = '/new_wallet_from_welcome';
static const restoreFromWelcome = '/restore_from_welcome';
static const seed = '/seed';
static const restoreOptions = '/restore_options';
static const restoreOptionsFromWelcome = '/restore_options_from_welcome';
static const restoreWalletOptions = '/restore_seed_keys';
static const restoreWalletOptionsFromWelcome = '/restore_wallet_options_from_welcome';
static const restoreWalletFromSeed = '/restore_wallet_from_seed';
static const restoreWalletFromKeys = '/restore_wallet_from_keys';
static const restoreWalletFromSeedKeys = '/restore_wallet_from_seeds_keys';
static const dashboard = '/dashboard';
static const send = '/send';
static const transactionDetails = '/transaction_info';
@ -57,8 +52,6 @@ class Routes {
static const buyWebView = '/buy_web_view';
static const unspentCoinsList = '/unspent_coins_list';
static const unspentCoinsDetails = '/unspent_coins_details';
static const moneroRestoreWalletFromWelcome = '/monero_restore_wallet';
static const moneroNewWalletFromWelcome = '/monero_new_wallet';
static const addressPage = '/address_page';
static const fullscreenQR = '/fullscreen_qr';
static const ioniaWelcomePage = '/cake_pay_welcome_page';
@ -84,12 +77,17 @@ class Routes {
static const displaySettingsPage = '/display_settings_page';
static const otherSettingsPage = '/other_settings_page';
static const advancedPrivacySettings = '/advanced_privacy_settings';
static const desktop_actions = '/desktop_actions';
static const transactionsPage = '/transactions_page';
static const sweepingWalletPage = '/sweeping_wallet_page';
static const walletPasswordUnlock = '/wallet_password_unlock';
static const walletUnlockLoadable = '/wallet_unlock_loadable';
static const anonPayInvoicePage = '/anon_pay_invoice_page';
static const anonPayReceivePage = '/anon_pay_receive_page';
static const anonPayDetailsPage = '/anon_pay_details_page';
static const payfuraPage = '/pay_fura_page';
static const desktop_actions = '/desktop_actions';
static const transactionsPage = '/transactions_page';
static const setup_2faPage = '/setup_2fa_page';
static const setup_2faQRPage = '/setup_2fa_qr_page';
static const totpAuthCodePage = '/totp_auth_code_page';
static const modify2FAPage = '/modify_2fa_page';
}

View file

@ -20,13 +20,33 @@ class AnonpayDetailsPage extends BasePage {
final AnonpayDetailsViewModel anonpayDetailsViewModel;
@override
Widget body(BuildContext context) {
Widget body(BuildContext context) => AnonpayDetailsPageBody(anonpayDetailsViewModel);
}
class AnonpayDetailsPageBody extends StatefulWidget {
AnonpayDetailsPageBody(this.anonpayDetailsViewModel);
final AnonpayDetailsViewModel anonpayDetailsViewModel;
@override
State<AnonpayDetailsPageBody> createState() => _AnonpayDetailsPageBodyState();
}
class _AnonpayDetailsPageBodyState extends State<AnonpayDetailsPageBody> {
@override
void dispose() {
super.dispose();
widget.anonpayDetailsViewModel.timer?.cancel();
}
@override
Widget build(BuildContext context) {
return SectionStandardList(
context: context,
sectionCount: 1,
itemCounter: (int _) => anonpayDetailsViewModel.items.length,
itemCounter: (int _) => widget.anonpayDetailsViewModel.items.length,
itemBuilder: (_, __, index) {
final item = anonpayDetailsViewModel.items[index];
final item = widget.anonpayDetailsViewModel.items[index];
if (item is DetailsListStatusItem) {
return StandardListStatusRow(title: item.title, value: item.value);
@ -37,20 +57,18 @@ class AnonpayDetailsPage extends BasePage {
id: item.id,
create: item.createdAt,
pair: item.pair,
currentTheme: anonpayDetailsViewModel.settingsStore.currentTheme.type,
currentTheme: widget.anonpayDetailsViewModel.settingsStore.currentTheme.type,
onTap: item.onTap,
);
}
return GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(text: item.value));
showBar<void>(context, S.of(context).transaction_details_copied(item.title));
},
child: ListRow(title: '${item.title}:', value: item.value),
);
return GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(text: item.value));
showBar<void>(context, S.of(context).transaction_details_copied(item.title));
},
child: ListRow(title: '${item.title}:', value: item.value),
);
});
}
}

View file

@ -148,7 +148,7 @@ class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
),
))
: Container(),
backgroundColor: Theme.of(context).backgroundColor,
backgroundColor: Theme.of(context).colorScheme.background,
border: null),
resizeToAvoidBottomInset: false,
body: PinCode((pin, _) => widget.authViewModel.auth(password: pin),

View file

@ -79,7 +79,10 @@ class BackupPage extends BasePage {
isLoading: backupViewModelBase.state is IsExecutingState,
onPressed: () => onExportBackup(context),
text: S.of(context).export_backup,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white)),
bottom: 24,
left: 24,

View file

@ -38,14 +38,20 @@ class EditBackupPasswordPage extends BasePage {
keyboardType: TextInputType.visiblePassword,
controller: textEditingController,
style: TextStyle(
fontSize: 26,
color: Theme.of(context).primaryTextTheme!.headline6!.color!)))),
fontSize: 26,
color: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!)))),
Positioned(
child: Observer(
builder: (_) => PrimaryButton(
onPressed: () => onSave(context),
text: S.of(context).save,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white,
isDisabled: !editBackupPasswordViewModel.canSave)),
bottom: 24,

View file

@ -1,5 +1,4 @@
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
@ -21,8 +20,6 @@ abstract class BasePage extends StatelessWidget {
String? get title => null;
bool get canUseCloseIcon => false;
Color get backgroundLightColor => Colors.white;
Color get backgroundDarkColor => PaletteDark.backgroundColor;
@ -51,29 +48,24 @@ abstract class BasePage extends StatelessWidget {
}
final _backButton = Icon(Icons.arrow_back_ios,
color: titleColor ?? Theme.of(context).primaryTextTheme.headline6!.color!,
color: titleColor ?? Theme.of(context).primaryTextTheme!.titleLarge!.color!,
size: 16,);
final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics(
child: SizedBox(
height: isMobileView ? 37 : 45,
width: isMobileView ? 37 : 45,
height: 37,
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: Semantics(
label: canUseCloseIcon && !isMobileView ? 'Close' : 'Back',
label: 'Back',
child: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateColor.resolveWith(
(states) => Colors.transparent),
),
onPressed: () => onClose(context),
child:
canUseCloseIcon && !isMobileView ? _closeButton : _backButton,
child: _backButton,
),
),
),
@ -91,7 +83,7 @@ abstract class BasePage extends StatelessWidget {
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor ??
Theme.of(context).primaryTextTheme!.headline6!.color!),
Theme.of(context).primaryTextTheme!.titleLarge!.color!),
);
}

View file

@ -80,7 +80,9 @@ class PreOrderPage extends BasePage {
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.bodyText1!
keyboardBarColor: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.backgroundColor!,
nextFocus: false,
actions: [
@ -91,7 +93,7 @@ class PreOrderPage extends BasePage {
]),
child: Container(
height: 0,
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Observer(builder: (_) => Column(
@ -102,9 +104,9 @@ class PreOrderPage extends BasePage {
bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme.subtitle1!.color!,
Theme.of(context).primaryTextTheme!.titleMedium!.color!,
Theme.of(context)
.primaryTextTheme.subtitle1!
.primaryTextTheme!.titleMedium!
.decorationColor!,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
@ -160,11 +162,11 @@ class PreOrderPage extends BasePage {
),
),
hintText: '0.00',
borderColor: Theme.of(context).primaryTextTheme.bodyText1!.decorationColor!,
borderColor: Theme.of(context).primaryTextTheme!.bodyLarge!.decorationColor!,
borderWidth: 0.5,
textStyle: TextStyle(fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme.headline5!.decorationColor!,
color: Theme.of(context).primaryTextTheme!.headlineSmall!.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 36,
),
@ -179,7 +181,7 @@ class PreOrderPage extends BasePage {
S.of(context).buy_with + ':',
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.headline6!.color!,
color: Theme.of(context).primaryTextTheme.titleLarge!.color!,
fontSize: 18,
fontWeight: FontWeight.bold
),
@ -246,7 +248,7 @@ class PreOrderPage extends BasePage {
? S.of(context).buy
: S.of(context).buy_with +
' ${buyViewModel.selectedProvider!.description.title}',
color: Theme.of(context).accentTextTheme.bodyText1!.color!,
color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
textColor: Colors.white,
isLoading: buyViewModel.isRunning,
isDisabled: (buyViewModel.selectedProvider == null) ||

View file

@ -29,12 +29,15 @@ class ContactListPage extends BasePage {
height: 32.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).accentTextTheme.caption!.color!),
color: Theme.of(context)
.accentTextTheme!
.bodySmall!
.color!),
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Icon(Icons.add,
color: Theme.of(context).primaryTextTheme.headline6!.color!,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
size: 22.0),
ButtonTheme(
minWidth: 32.0,
@ -64,9 +67,9 @@ class ContactListPage extends BasePage {
return CollapsibleSectionList(
context: context,
sectionCount: 2,
themeColor: Theme.of(context).primaryTextTheme.headline6!.color!,
themeColor: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
dividerThemeColor:
Theme.of(context).primaryTextTheme.caption!.decorationColor!,
Theme.of(context).primaryTextTheme!.bodySmall!.decorationColor!,
sectionTitleBuilder: (_, int sectionIndex) {
var title = S.current.contact_list_contacts;
@ -120,6 +123,7 @@ class ContactListPage extends BasePage {
if (isCopied) {
await Clipboard.setData(ClipboardData(text: contact.address));
await showBar<void>(context, S.of(context).copied_to_clipboard);
}
},
child: Container(
@ -139,7 +143,7 @@ class ContactListPage extends BasePage {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.headline6!.color!),
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!),
),
)
)

View file

@ -1,13 +1,11 @@
import 'package:cake_wallet/core/validator.dart';
import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/currency.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/core/contact_name_validator.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
@ -33,8 +31,8 @@ class ContactPage extends BasePage {
_addressController
.addListener(() => contactViewModel.address = _addressController.text);
autorun((_) =>
_currencyTypeController.text = contactViewModel.currency?.toString()??'');
autorun((_) => _currencyTypeController.text =
contactViewModel.currency?.toString() ?? '');
}
@override
@ -49,7 +47,8 @@ class ContactPage extends BasePage {
@override
Widget body(BuildContext context) {
final downArrow = Image.asset('assets/images/arrow_bottom_purple_icon.png',
color: Theme.of(context).primaryTextTheme!.overline!.color!, height: 8);
color: Theme.of(context).primaryTextTheme!.labelSmall!.color!,
height: 8);
reaction((_) => contactViewModel.state, (ExecutionState state) {
if (state is FailureState) {
@ -61,96 +60,107 @@ class ContactPage extends BasePage {
}
});
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
BaseTextFormField(
controller: _nameController,
hintText: S.of(context).contact_name,
validator: ContactNameValidator()),
Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
child: InkWell(
onTap: () => _presentCurrencyPicker(context),
child: IgnorePointer(
child: BaseTextFormField(
controller: _currencyTypeController,
hintText: S.of(context).settings_currency,
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[downArrow],
),
)),
return Observer(
builder: (_) => ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
BaseTextFormField(
controller: _nameController,
hintText: S.of(context).contact_name,
validator: ContactNameValidator()),
Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
child: InkWell(
onTap: () => _presentCurrencyPicker(context),
child: IgnorePointer(
child: BaseTextFormField(
controller: _currencyTypeController,
hintText: S.of(context).settings_currency,
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[downArrow],
),
)),
),
),
),
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Observer(
builder: (_) => AddressTextField(
if (contactViewModel.currency != null)
Padding(
padding: EdgeInsets.only(top: 20),
child: AddressTextField(
controller: _addressController,
options: [
AddressTextFieldOption.paste,
AddressTextFieldOption.qrCode,
],
buttonColor: Theme.of(context).accentTextTheme!.headline3!.color!,
buttonColor: Theme.of(context)
.accentTextTheme!
.displaySmall!
.color!,
iconColor: PaletteDark.gray,
borderColor: Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!,
validator: TextValidator()
// AddressValidator(
// type: contactViewModel.currency),
)),
)
],
),
),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Row(
children: <Widget>[
Expanded(
child: PrimaryButton(
onPressed: () {
contactViewModel.reset();
_nameController.text = '';
_addressController.text = '';
},
text: S.of(context).reset,
color: Colors.orange,
textColor: Colors.white),
borderColor: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.backgroundColor!,
validator:
AddressValidator(type: contactViewModel.currency!),
),
)
],
),
SizedBox(width: 20),
Expanded(
child: Observer(
builder: (_) => PrimaryButton(
onPressed: () async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Row(
children: <Widget>[
Expanded(
child: PrimaryButton(
onPressed: () {
contactViewModel.reset();
_nameController.text = '';
_addressController.text = '';
},
text: S.of(context).reset,
color: Colors.orange,
textColor: Colors.white),
),
SizedBox(width: 20),
Expanded(
child: Observer(
builder: (_) => PrimaryButton(
onPressed: () async {
if (_formKey.currentState != null &&
!_formKey.currentState!.validate()) {
return;
}
await contactViewModel.save();
},
text: S.of(context).save,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isDisabled: !contactViewModel.isReady)))
],
));
await contactViewModel.save();
},
text: S.of(context).save,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white,
isDisabled: !contactViewModel.isReady)))
],
)),
);
}
void _presentCurrencyPicker(BuildContext context) {
showPopUp<void>(
builder: (_) => CurrencyPicker(
selectedAtIndex:
contactViewModel.currency != null
? contactViewModel.currencies.indexOf(contactViewModel.currency!)
: 0,
selectedAtIndex: contactViewModel.currency != null
? contactViewModel.currencies
.indexOf(contactViewModel.currency!)
: -1,
items: contactViewModel.currencies,
title: S.of(context).please_select,
hintText: S.of(context).search_currency,

View file

@ -1,8 +1,10 @@
import 'dart:async';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/main_actions.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/market_place_page.dart';
import 'package:cake_wallet/utils/version_comparator.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
@ -22,8 +24,12 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
class DashboardPage extends StatelessWidget {
DashboardPage({
@ -71,7 +77,7 @@ class _DashboardPageView extends BasePage {
(BuildContext context, Widget scaffold) => Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Theme.of(context).accentColor,
Theme.of(context).colorScheme.secondary,
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).primaryColor,
], begin: Alignment.topRight, end: Alignment.bottomLeft)),
@ -93,7 +99,10 @@ class _DashboardPageView extends BasePage {
@override
Widget trailing(BuildContext context) {
final menuButton = Image.asset('assets/images/menu.png',
color: Theme.of(context).accentTextTheme.headline2!.backgroundColor!);
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor);
return Container(
alignment: Alignment.centerRight,
@ -117,7 +126,7 @@ class _DashboardPageView extends BasePage {
@override
Widget body(BuildContext context) {
final controller = PageController(initialPage: initialPage);
reaction((_) => dashboardViewModel.shouldShowMarketPlaceInDashboard, (bool value) {
if (!dashboardViewModel.shouldShowMarketPlaceInDashboard) {
controller.jumpToPage(0);
@ -131,7 +140,7 @@ class _DashboardPageView extends BasePage {
} else {
controller.jumpToPage(0);
}
});
});
_setEffects(context);
return SafeArea(
@ -161,7 +170,7 @@ class _DashboardPageView extends BasePage {
dotColor: Theme.of(context).indicatorColor,
activeDotColor: Theme.of(context)
.accentTextTheme!
.headline4!
.headlineMedium!
.backgroundColor!),
),
);
@ -180,7 +189,10 @@ class _DashboardPageView extends BasePage {
: Colors.transparent,
width: 1,
),
color: Theme.of(context).textTheme.headline6!.backgroundColor!,
color: Theme.of(context)
.textTheme!
.titleLarge!
.backgroundColor!,
),
child: Container(
padding: EdgeInsets.only(left: 32, right: 32),
@ -201,12 +213,12 @@ class _DashboardPageView extends BasePage {
dashboardViewModel) ??
true
? Theme.of(context)
.accentTextTheme
.headline2!
.accentTextTheme!
.displayMedium!
.backgroundColor!
: Theme.of(context)
.accentTextTheme
.headline3!
.accentTextTheme!
.displaySmall!
.backgroundColor!),
title: action.name(context),
onClick: () async => await action.onTap(
@ -216,8 +228,8 @@ class _DashboardPageView extends BasePage {
true
? null
: Theme.of(context)
.accentTextTheme
.headline3!
.accentTextTheme!
.displaySmall!
.backgroundColor!,
),
))
@ -266,6 +278,25 @@ class _DashboardPageView extends BasePage {
}
});
final sharedPrefs = await SharedPreferences.getInstance();
final currentAppVersion =
VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion);
final lastSeenAppVersion = sharedPrefs.getInt(PreferencesKey.lastSeenAppVersion);
final isNewInstall = sharedPrefs.getBool(PreferencesKey.isNewInstall);
if (currentAppVersion != lastSeenAppVersion && !isNewInstall!) {
await Future<void>.delayed(Duration(seconds: 1));
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
return ReleaseNotesScreen(
title: 'Version ${dashboardViewModel.settingsStore.appVersion}');
});
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
} else if (isNewInstall!) {
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
}
var needToPresentYat = false;
var isInactive = false;

View file

@ -1,9 +1,12 @@
import 'dart:async';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/release_notes/release_notes_screen.dart';
import 'package:cake_wallet/src/screens/yat_emoji_id.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/utils/version_comparator.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
@ -11,6 +14,7 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_v
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/router.dart' as Router;
import 'package:shared_preferences/shared_preferences.dart';
class DesktopDashboardPage extends StatelessWidget {
DesktopDashboardPage({
@ -33,7 +37,7 @@ class DesktopDashboardPage extends StatelessWidget {
_setEffects(context);
return Container(
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -107,5 +111,24 @@ class DesktopDashboardPage extends StatelessWidget {
needToPresentYat = true;
});
final sharedPrefs = await SharedPreferences.getInstance();
final currentAppVersion =
VersionComparator.getExtendedVersionNumber(dashboardViewModel.settingsStore.appVersion);
final lastSeenAppVersion = sharedPrefs.getInt(PreferencesKey.lastSeenAppVersion);
final isNewInstall = sharedPrefs.getBool(PreferencesKey.isNewInstall);
if (currentAppVersion != lastSeenAppVersion && !isNewInstall!) {
await Future<void>.delayed(Duration(seconds: 1));
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
return ReleaseNotesScreen(
title: 'Version ${dashboardViewModel.settingsStore.appVersion}');
});
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
} else if (isNewInstall!) {
sharedPrefs.setInt(PreferencesKey.lastSeenAppVersion, currentAppVersion);
}
}
}

View file

@ -30,7 +30,7 @@ class DesktopActionButton extends StatelessWidget {
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Theme.of(context).textTheme.headline6!.backgroundColor!,
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!,
),
child: Center(
child: Row(
@ -41,8 +41,14 @@ class DesktopActionButton extends StatelessWidget {
height: 30,
width: 30,
color: isEnabled
? Theme.of(context).accentTextTheme.headline2!.backgroundColor!
: Theme.of(context).accentTextTheme.headline3!.backgroundColor!,
? Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!
: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!,
),
const SizedBox(width: 10),
AutoSizeText(
@ -52,7 +58,10 @@ class DesktopActionButton extends StatelessWidget {
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
color: isEnabled
? Theme.of(context).accentTextTheme.headline2!.backgroundColor!
? Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!
: null,
height: 1,
),

View file

@ -16,7 +16,7 @@ class SideMenuItem extends StatelessWidget {
Color _setColor(BuildContext context) {
if (isSelected) {
return Theme.of(context).primaryTextTheme.headline6!.color!;
return Theme.of(context).primaryTextTheme!.titleLarge!.color!;
} else {
return Theme.of(context).highlightColor;
}

View file

@ -126,7 +126,7 @@ class DesktopSidebarWrapper extends BasePage {
children: [
child,
Container(
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
padding: EdgeInsets.all(20),
child: Navigator(
initialRoute: Routes.support,

View file

@ -1,8 +1,8 @@
import 'package:another_flushbar/flushbar.dart';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/desktop_dropdown_item.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
@ -18,8 +18,10 @@ import 'package:flutter_mobx/flutter_mobx.dart';
class DesktopWalletSelectionDropDown extends StatefulWidget {
final WalletListViewModel walletListViewModel;
final AuthService _authService;
DesktopWalletSelectionDropDown(this.walletListViewModel, {Key? key}) : super(key: key);
DesktopWalletSelectionDropDown(this.walletListViewModel, this._authService, {Key? key})
: super(key: key);
@override
State<DesktopWalletSelectionDropDown> createState() => _DesktopWalletSelectionDropDownState();
@ -35,13 +37,13 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
'assets/images/new_wallet.png',
height: 12,
width: 12,
color: Theme.of(context).primaryTextTheme.headline6!.color!,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
);
Image _restoreWalletImage(BuildContext context) => Image.asset(
'assets/images/restore_wallet.png',
height: 12,
width: 12,
color: Theme.of(context).primaryTextTheme.headline6!.color!,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
);
Flushbar<void>? _progressBar;
@ -91,8 +93,8 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
onChanged: (item) {
item?.onSelected();
},
dropdownColor: themeData.textTheme.bodyText1?.decorationColor,
style: TextStyle(color: themeData.primaryTextTheme.headline6?.color),
dropdownColor: themeData.textTheme!.bodyLarge?.decorationColor,
style: TextStyle(color: themeData.primaryTextTheme!.titleLarge?.color),
selectedItemBuilder: (context) => dropDownItems.map((item) => item.child).toList(),
value: dropDownItems.firstWhere((element) => element.isSelected),
underline: const SizedBox(),
@ -140,39 +142,26 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
}
Future<void> _loadWallet(WalletListItem wallet) async {
if (await widget.walletListViewModel.checkIfAuthRequired()) {
if (SettingsStoreBase.walletPasswordDirectInput) {
Navigator.of(context).pushNamed(
if (SettingsStoreBase.walletPasswordDirectInput) {
Navigator.of(context).pushNamed(
Routes.walletUnlockLoadable,
arguments: WalletUnlockArguments(
callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
if (isAuthenticatedSuccessfully) {
auth.close();
setState(() {});
}
}, walletName: wallet.name,
walletType: wallet.type));
callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
if (isAuthenticatedSuccessfully) {
auth.close();
setState(() {});
}
}, walletName: wallet.name,
walletType: wallet.type));
return;
}
widget._authService.authenticateAction(context,
onAuthSuccess: (isAuthenticatedSuccessfully) async {
if (!isAuthenticatedSuccessfully) {
return;
}
await Navigator.of(context).pushNamed(Routes.auth,
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
if (!isAuthenticatedSuccessfully) {
return;
}
try {
auth.changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name));
await widget.walletListViewModel.loadWallet(wallet);
auth.hideProgressText();
auth.close();
setState(() {});
} catch (e) {
auth.changeProcessText(
S.of(context).wallet_list_failed_to_load(wallet.name, e.toString()));
}
});
} else {
try {
changeProcessText(S.of(context).wallet_list_loading_wallet(wallet.name));
await widget.walletListViewModel.loadWallet(wallet);
@ -181,7 +170,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
} catch (e) {
changeProcessText(S.of(context).wallet_list_failed_to_load(wallet.name, e.toString()));
}
}
});
}
void _navigateToCreateWallet() {

View file

@ -23,7 +23,7 @@ class DropDownItemWidget extends StatelessWidget {
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.headline6!.color!,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,

View file

@ -45,7 +45,11 @@ class ActionButton extends StatelessWidget {
title,
style: TextStyle(
fontSize: 10,
color: textColor ?? Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
color: textColor ??
Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!),
)
],
),

View file

@ -6,6 +6,7 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/share_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
@ -26,11 +27,23 @@ class AddressPage extends BasePage {
required this.addressListViewModel,
required this.dashboardViewModel,
required this.receiveOptionViewModel,
}) : _cryptoAmountFocus = FocusNode();
}) : _cryptoAmountFocus = FocusNode(),
_formKey = GlobalKey<FormState>(),
_amountController = TextEditingController(){
_amountController.addListener(() {
if (_formKey.currentState!.validate()) {
addressListViewModel.changeAmount(
_amountController.text,
);
}
});
}
final WalletAddressListViewModel addressListViewModel;
final DashboardViewModel dashboardViewModel;
final ReceiveOptionViewModel receiveOptionViewModel;
final TextEditingController _amountController;
final GlobalKey<FormState> _formKey;
final FocusNode _cryptoAmountFocus;
@ -47,21 +60,56 @@ class AddressPage extends BasePage {
bool effectsInstalled = false;
@override
Color get titleColor => Colors.white;
Widget? leading(BuildContext context) {
final _backButton = Icon(
Icons.arrow_back_ios,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
size: 16,
);
final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme
: closeButtonImage;
@override
bool get canUseCloseIcon => true;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics(
child: SizedBox(
height: isMobileView ? 37 : 45,
width: isMobileView ? 37 : 45,
child: ButtonTheme(
minWidth: double.minPositive,
child: Semantics(
label: !isMobileView ? 'Close' : 'Back',
child: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateColor.resolveWith(
(states) => Colors.transparent),
),
onPressed: () => onClose(context),
child: !isMobileView ? _closeButton : _backButton,
),
),
),
),
);
}
@override
Widget middle(BuildContext context) =>
PresentReceiveOptionPicker(receiveOptionViewModel: receiveOptionViewModel);
PresentReceiveOptionPicker(
receiveOptionViewModel: receiveOptionViewModel,
hasWhiteBackground: currentTheme.type == ThemeType.light,
);
@override
Widget Function(BuildContext, Widget) get rootWrapper =>
(BuildContext context, Widget scaffold) => Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Theme.of(context).accentColor,
Theme.of(context).colorScheme.secondary,
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).primaryColor,
], begin: Alignment.topRight, end: Alignment.bottomLeft)),
@ -69,28 +117,30 @@ class AddressPage extends BasePage {
@override
Widget? trailing(BuildContext context) {
final shareImage = Image.asset('assets/images/share.png',
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
return !addressListViewModel.hasAddressList
? Material(
color: Colors.transparent,
child: IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
iconSize: 25,
onPressed: () {
ShareUtil.share(
text: addressListViewModel.address.address,
context: context,
);
},
icon: shareImage,
),
)
: null;
return Material(
color: Colors.transparent,
child: IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
iconSize: 25,
onPressed: () {
ShareUtil.share(
text: addressListViewModel.uri.toString(),
context: context,
);
},
icon: Icon(
Icons.share,
size: 20,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
),
),
);
}
@override
@ -128,7 +178,10 @@ class AddressPage extends BasePage {
tapOutsideToDismiss: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.bodyText1!.backgroundColor!,
keyboardBarColor: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@ -137,16 +190,18 @@ class AddressPage extends BasePage {
)
]),
child: Container(
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
padding: EdgeInsets.fromLTRB(24, 0, 24, 32),
child: Column(
children: <Widget>[
Expanded(
child: Observer(builder: (_) => QRWidget(
addressListViewModel: addressListViewModel,
amountTextFieldFocusNode: _cryptoAmountFocus,
isAmountFieldShow: !addressListViewModel.hasAccounts,
isLight: dashboardViewModel.settingsStore.currentTheme.type == ThemeType.light))
),
Expanded(
child: Observer(
builder: (_) => QRWidget(
formKey: _formKey,
addressListViewModel: addressListViewModel,
amountTextFieldFocusNode: _cryptoAmountFocus,
amountController: _amountController,
isLight: dashboardViewModel.settingsStore.currentTheme.type ==
ThemeType.light))),
Observer(builder: (_) {
return addressListViewModel.hasAddressList
? GestureDetector(
@ -158,8 +213,15 @@ class AddressPage extends BasePage {
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(25)),
border: Border.all(
color: Theme.of(context).textTheme.subtitle1!.color!, width: 1),
color: Theme.of(context).buttonColor),
color: Theme.of(context)
.textTheme!
.titleMedium!
.color!,
width: 1),
color: Theme.of(context)
.textTheme!
.titleLarge!
.backgroundColor!),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -173,15 +235,17 @@ class AddressPage extends BasePage {
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme
.headline2!
.accentTextTheme!
.displayMedium!
.backgroundColor!),
)),
Icon(
Icons.arrow_forward_ios,
size: 14,
color:
Theme.of(context).accentTextTheme.headline2!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
)
],
),
@ -191,7 +255,10 @@ class AddressPage extends BasePage {
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
color: Theme.of(context).accentTextTheme.headline3!.backgroundColor!));
color: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!));
})
],
),

View file

@ -37,19 +37,19 @@ class AnonpayTransactionRow extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.headline2!.backgroundColor!)),
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)),
Text(amount + ' ' + currency,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.headline2!.backgroundColor!))
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!))
]),
SizedBox(height: 5),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
Text(createdAt,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme.overline!.backgroundColor!))
color: Theme.of(context).textTheme!.labelSmall!.backgroundColor!))
])
],
))

View file

@ -8,187 +8,240 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/src/widgets/introducing_card.dart';
import 'package:cake_wallet/generated/i18n.dart';
class BalancePage extends StatelessWidget{
class BalancePage extends StatelessWidget {
BalancePage({required this.dashboardViewModel, required this.settingsStore});
final DashboardViewModel dashboardViewModel;
final SettingsStore settingsStore;
Color get backgroundLightColor =>
settingsStore.currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPress: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: ResponsiveLayoutUtil.instance.isMobile(context) ? 56 : 16),
onLongPress: () => dashboardViewModel.balanceViewModel.isReversing =
!dashboardViewModel.balanceViewModel.isReversing,
onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing =
!dashboardViewModel.balanceViewModel.isReversing,
child: SingleChildScrollView(
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
SizedBox(height: 56),
Container(
margin: const EdgeInsets.only(left: 24, bottom: 16),
child: Observer(builder: (_) {
return Text(
dashboardViewModel.balanceViewModel.asset,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center);
})),
margin: const EdgeInsets.only(left: 24, bottom: 16),
child: Observer(builder: (_) {
return Text(dashboardViewModel.balanceViewModel.asset,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center);
})),
Observer(builder: (_) {
if (dashboardViewModel.balanceViewModel.isShowCard){
if (dashboardViewModel.balanceViewModel.isShowCard) {
return IntroducingCard(
title: S.of(context).introducing_cake_pay,
title: S.of(context).introducing_cake_pay,
subTitle: S.of(context).cake_pay_learn_more,
borderColor: settingsStore.currentTheme.type == ThemeType.bright
? Color.fromRGBO(255, 255, 255, 0.2)
: Colors.transparent,
closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard
);
closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard);
}
return Container ();
return Container();
}),
Observer(builder: (_) {
return ListView.separated(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 8)),
itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length,
itemBuilder: (__, index) {
final balance = dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
return buildBalanceRow(context,
availableBalanceLabel: '${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 8)),
itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length,
itemBuilder: (__, index) {
final balance =
dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
return buildBalanceRow(context,
availableBalanceLabel:
'${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
availableBalance: balance.availableBalance,
availableFiatBalance: balance.fiatAvailableBalance,
additionalBalanceLabel: '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
additionalBalanceLabel:
'${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
additionalBalance: balance.additionalBalance,
additionalFiatBalance: balance.fiatAdditionalBalance,
frozenBalance: balance.frozenBalance,
frozenFiatBalance: balance.fiatFrozenBalance,
currency: balance.formattedAssetTitle);
});
})
])));
});
})
])));
}
Widget buildBalanceRow(BuildContext context,
{required String availableBalanceLabel,
{required String availableBalanceLabel,
required String availableBalance,
required String availableFiatBalance,
required String additionalBalanceLabel,
required String additionalBalance,
required String additionalFiatBalance,
required String frozenBalance,
required String frozenFiatBalance,
required String currency}) {
return Container(
return Container(
margin: const EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
color:Theme.of(context).textTheme!.headline6!.backgroundColor!
),
borderRadius: BorderRadius.circular(30.0),
border: Border.all(
color: settingsStore.currentTheme.type == ThemeType.bright
? Color.fromRGBO(255, 255, 255, 0.2)
: Colors.transparent,
width: 1,
),
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!),
child: Container(
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 4,),
Text('${availableBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
SizedBox(
height: 4,
),
Text('${availableBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.headline3!
.backgroundColor!,
.accentTextTheme!
.displaySmall!
.backgroundColor!,
height: 1)),
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
AutoSizeText(
availableBalance,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.w900,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
Text(currency,
style: TextStyle(
fontSize: 28,
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1)),
]),
SizedBox(height: 4,),
Text('${availableFiatBalance}',
SizedBox(height: 5),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
AutoSizeText(availableBalance,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.w900,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
Text(currency,
style: TextStyle(
fontSize: 28,
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1)),
]),
SizedBox(
height: 4,
),
Text('${availableFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1)),
SizedBox(height: 26),
Text('${additionalBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.headline3!
.backgroundColor!,
height: 1)),
SizedBox(height: 8),
AutoSizeText(
additionalBalance,
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1)),
SizedBox(height: 26),
if (frozenBalance.isNotEmpty)
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Text(S.current.frozen_balance,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.displaySmall!
.backgroundColor!,
height: 1)),
SizedBox(height: 8),
AutoSizeText(frozenBalance,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
SizedBox(height: 4,),
Text('${additionalFiatBalance}',
SizedBox(height: 4),
Text(
frozenFiatBalance,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
),
SizedBox(height: 24)
]),
Text('${additionalBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!,
height: 1)),
SizedBox(height: 8),
AutoSizeText(additionalBalance,
style: TextStyle(
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
SizedBox(
height: 4,
),
Text(
'${additionalFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.headline2!
.backgroundColor!,
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
)
])),
)
])),
);
}
}

View file

@ -36,6 +36,9 @@ class DateSectionRaw extends StatelessWidget {
child: Text(title,
style: TextStyle(
fontSize: 12,
color: Theme.of(context).textTheme!.overline!.backgroundColor!)));
color: Theme.of(context)
.textTheme!
.labelSmall!
.backgroundColor!)));
}
}

View file

@ -1,13 +1,9 @@
import 'dart:ui';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/filter_tile.dart';
import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
//import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
@ -16,94 +12,97 @@ class FilterWidget extends StatelessWidget {
FilterWidget({required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
final closeIcon = Image.asset('assets/images/close.png', color: Palette.darkBlueCraiola);
@override
Widget build(BuildContext context) {
const sectionDivider = const SectionDivider();
return AlertBackground(
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(24)),
child: Container(
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(
padding: EdgeInsets.all(24.0),
child: Text(
S.of(context).filter_by,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.overline!.color!,
fontSize: 16,
fontFamily: 'Lato',
decoration: TextDecoration.none,
),
return PickerWrapperWidget(
children: [
Padding(
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(24)),
child: Container(
color: Theme.of(context).textTheme!.bodyLarge!.decorationColor!,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.all(24.0),
child: Text(
S.of(context).filter_by,
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme!
.labelSmall!
.color!,
fontSize: 16,
fontFamily: 'Lato',
decoration: TextDecoration.none,
),
),
sectionDivider,
ListView.separated(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: dashboardViewModel.filterItems.length,
separatorBuilder: (context, _) => sectionDivider,
itemBuilder: (_, index1) {
final title = dashboardViewModel.filterItems.keys.elementAt(index1);
final section = dashboardViewModel.filterItems.values.elementAt(index1);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 20, left: 24, right: 24),
child: Text(
title,
style: TextStyle(
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
decoration: TextDecoration.none),
),
),
sectionDivider,
ListView.separated(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: dashboardViewModel.filterItems.length,
separatorBuilder: (context, _) => sectionDivider,
itemBuilder: (_, index1) {
final title = dashboardViewModel.filterItems.keys
.elementAt(index1);
final section = dashboardViewModel.filterItems.values
.elementAt(index1);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding:
EdgeInsets.only(top: 20, left: 24, right: 24),
child: Text(
title,
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!,
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
decoration: TextDecoration.none),
),
ListView.builder(
padding: EdgeInsets.symmetric(vertical: 8.0),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: section.length,
itemBuilder: (_, index2) {
final item = section[index2];
final content = Observer(
builder: (_) => StandardCheckbox(
value: item.value(),
caption: item.caption,
gradientBackground: true,
borderColor: Theme.of(context).dividerColor,
iconColor: Colors.white,
onChanged: (value) => item.onChanged(),
));
return FilterTile(child: content);
},
)
],
);
},
),
]),
),
),
),
],
),
ListView.builder(
padding: EdgeInsets.symmetric(vertical: 8.0),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: section.length,
itemBuilder: (_, index2) {
final item = section[index2];
final content = Observer(
builder: (_) => StandardCheckbox(
value: item.value(),
caption: item.caption,
gradientBackground: true,
borderColor:
Theme.of(context).dividerColor,
iconColor: Colors.white,
onChanged: (value) =>
item.onChanged(),
));
return FilterTile(child: content);
},
)
],
);
},
),
]),
),
),
AlertCloseButton(image: closeIcon)
],
),
)
],
);
}
}

View file

@ -12,7 +12,7 @@ class HeaderRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final filterIcon = Image.asset('assets/images/filter_icon.png',
color: Theme.of(context).textTheme!.caption!.decorationColor!);
color: Theme.of(context).textTheme!.bodySmall!.decorationColor!);
return Container(
height: 52,
@ -25,10 +25,12 @@ class HeaderRow extends StatelessWidget {
Text(
S.of(context).transactions,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
),
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!),
),
GestureDetector(
onTap: () {
@ -43,8 +45,7 @@ class HeaderRow extends StatelessWidget {
width: 36,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).textTheme!.overline!.color!
),
color: Theme.of(context).textTheme!.labelSmall!.color!),
child: filterIcon,
),
)

View file

@ -23,7 +23,7 @@ class MarketPlacePage extends StatelessWidget {
child: RawScrollbar(
thumbColor: Colors.white.withOpacity(0.15),
radius: Radius.circular(20),
isAlwaysShown: true,
thumbVisibility: true,
thickness: 2,
controller: _scrollController,
child: Padding(
@ -37,7 +37,10 @@ class MarketPlacePage extends StatelessWidget {
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
),
),
Expanded(

View file

@ -84,9 +84,15 @@ class MenuWidgetState extends State<MenuWidget> {
final itemCount = SettingActions.all.length;
moneroIcon = Image.asset('assets/images/monero_menu.png',
color: Theme.of(context).accentTextTheme.overline!.decorationColor!);
color: Theme.of(context)
.accentTextTheme!
.labelSmall!
.decorationColor!);
bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
color: Theme.of(context).accentTextTheme.overline!.decorationColor!);
color: Theme.of(context)
.accentTextTheme!
.labelSmall!
.decorationColor!);
litecoinIcon = Image.asset('assets/images/litecoin_menu.png');
havenIcon = Image.asset('assets/images/haven_menu.png');
@ -108,7 +114,8 @@ class MenuWidgetState extends State<MenuWidget> {
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)),
child: Container(
color: Theme.of(context).textTheme.bodyText1!.decorationColor!,
color:
Theme.of(context).textTheme!.bodyLarge!.decorationColor!,
child: ListView.separated(
padding: EdgeInsets.only(top: 0),
itemBuilder: (_, index) {
@ -117,9 +124,14 @@ class MenuWidgetState extends State<MenuWidget> {
height: headerHeight,
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Theme.of(context).accentTextTheme.headline4!.color!,
Theme.of(context).accentTextTheme.headline4!.decorationColor!,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
Theme.of(context)
.accentTextTheme!
.headlineMedium!
.color!,
Theme.of(context)
.accentTextTheme!
.headlineMedium!
.decorationColor!, ], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
padding: EdgeInsets.only(
left: 24, top: fromTopEdge, right: 24, bottom: fromBottomEdge),
@ -149,8 +161,8 @@ class MenuWidgetState extends State<MenuWidget> {
widget.dashboardViewModel.subname,
style: TextStyle(
color: Theme.of(context)
.accentTextTheme
.overline!
.accentTextTheme!
.labelSmall!
.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 12),
@ -177,12 +189,15 @@ class MenuWidgetState extends State<MenuWidget> {
fromTopEdge: fromTopEdge,
onTap: () => item.onTap.call(context),
image: item.image,
title: item.name,
title: item.name.call(context),
);
},
separatorBuilder: (_, index) => Container(
height: 1,
color: Theme.of(context).primaryTextTheme.caption!.decorationColor!,
color: Theme.of(context)
.primaryTextTheme!
.bodySmall!
.decorationColor!,
),
itemCount: itemCount + 1),
)))

View file

@ -20,7 +20,7 @@ class OrderRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final iconColor =
Theme.of(context).primaryTextTheme!.headline1!.backgroundColor!;
Theme.of(context).primaryTextTheme!.displayLarge!.backgroundColor!;
final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor);
@ -48,14 +48,14 @@ class OrderRow extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!
)),
formattedAmount != null
? Text(formattedAmount! + ' ' + to,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!
))
: Container()
]),
@ -66,8 +66,10 @@ class OrderRow extends StatelessWidget {
Text(createdAtFormattedDate,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme!
.overline!.backgroundColor!))
color: Theme.of(context)
.textTheme!
.labelSmall!
.backgroundColor!))
])
],
)

View file

@ -9,14 +9,25 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
class PresentReceiveOptionPicker extends StatelessWidget {
PresentReceiveOptionPicker({required this.receiveOptionViewModel});
PresentReceiveOptionPicker(
{required this.receiveOptionViewModel, this.hasWhiteBackground = false});
final ReceiveOptionViewModel receiveOptionViewModel;
final bool hasWhiteBackground;
@override
Widget build(BuildContext context) {
final arrowBottom =
Image.asset('assets/images/arrow_bottom_purple_icon.png', color: Colors.white, height: 6);
final textIconTheme = hasWhiteBackground
? Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!
: Colors.white;
final arrowBottom = Image.asset(
'assets/images/arrow_bottom_purple_icon.png',
color: textIconTheme,
height: 6,
);
return TextButton(
onPressed: () => _showPicker(context),
@ -40,14 +51,14 @@ class PresentReceiveOptionPicker extends StatelessWidget {
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: Theme.of(context).accentTextTheme.headline2!.backgroundColor!),
color: textIconTheme),
),
Observer(
builder: (_) => Text(receiveOptionViewModel.selectedReceiveOption.toString(),
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.headline5!.color!)))
color: textIconTheme)))
],
),
SizedBox(width: 5),
@ -75,7 +86,7 @@ class PresentReceiveOptionPicker extends StatelessWidget {
margin: EdgeInsets.symmetric(horizontal: 24),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
),
child: Padding(
padding: const EdgeInsets.only(top: 24, bottom: 24),
@ -102,7 +113,10 @@ class PresentReceiveOptionPicker extends StatelessWidget {
Text(option.toString(),
textAlign: TextAlign.left,
style: textSmall(
color: Theme.of(context).primaryTextTheme.headline6!.color!,
color: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!,
).copyWith(
fontWeight:
value == option ? FontWeight.w800 : FontWeight.w500,

View file

@ -32,7 +32,7 @@ class SyncIndicator extends StatelessWidget {
child: Container(
height: 30,
width: syncIndicatorWidth,
color: Theme.of(context).textTheme!.headline6!.decorationColor!,
color: Theme.of(context).textTheme!.titleLarge!.decorationColor!,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
@ -44,7 +44,7 @@ class SyncIndicator extends StatelessWidget {
child: Container(
width: indicatorWidth,
height: 30,
color: Theme.of(context).textTheme!.headline6!.backgroundColor!,
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!,
)
)
: Offstage(),
@ -66,7 +66,7 @@ class SyncIndicator extends StatelessWidget {
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme!.headline6!.color!
color: Theme.of(context).textTheme!.titleLarge!.color!
),
),
)

View file

@ -26,14 +26,15 @@ class SyncIndicatorIcon extends StatelessWidget {
if (boolMode) {
indicatorColor = isSynced
? PaletteDark.brightGreen
: Theme.of(context).textTheme!.caption!.color!;
: Theme.of(context).textTheme!.bodySmall!.color!;
} else {
switch (value.toLowerCase()) {
case waiting:
indicatorColor = Colors.red;
break;
case actionRequired:
indicatorColor = Theme.of(context).textTheme!.headline2!.decorationColor!;
indicatorColor =
Theme.of(context).textTheme!.displayMedium!.decorationColor!;
break;
case created:
indicatorColor = PaletteDark.brightGreen;

View file

@ -43,14 +43,14 @@ class TradeRow extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!)),
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)),
formattedAmount != null
? Text(formattedAmount! + ' ' + amountCrypto,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color:
Theme.of(context).accentTextTheme!.headline2!.backgroundColor!))
Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!))
: Container()
]),
SizedBox(height: 5),
@ -59,7 +59,7 @@ class TradeRow extends StatelessWidget {
Text(createdAtFormattedDate!,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme!.overline!.backgroundColor!))
color: Theme.of(context).textTheme!.labelSmall!.backgroundColor!))
])
],
))

View file

@ -35,7 +35,7 @@ class TransactionRow extends StatelessWidget {
width: 36,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).textTheme!.overline!.decorationColor!
color: Theme.of(context).textTheme!.labelSmall!.decorationColor!
),
child: Image.asset(
direction == TransactionDirection.incoming
@ -55,13 +55,13 @@ class TransactionRow extends StatelessWidget {
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!
.headline2!.backgroundColor!)),
.displayMedium!.backgroundColor!)),
Text(formattedAmount,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme!
.headline2!.backgroundColor!))
.displayMedium!.backgroundColor!))
]),
SizedBox(height: 5),
Row(
@ -72,14 +72,14 @@ class TransactionRow extends StatelessWidget {
fontSize: 14,
color: Theme.of(context)
.textTheme!
.overline!
.labelSmall!
.backgroundColor!)),
Text(formattedFiatAmount,
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.textTheme!
.overline!
.labelSmall!
.backgroundColor!))
])
],

View file

@ -28,7 +28,7 @@ class TransactionsPage extends StatelessWidget {
return Container(
color: ResponsiveLayoutUtil.instance.isMobile(context)
? null
: Theme.of(context).backgroundColor,
: Theme.of(context).colorScheme.background,
padding: EdgeInsets.only(top: 24, bottom: 24),
child: Column(
children: <Widget>[
@ -121,7 +121,7 @@ class TransactionsPage extends StatelessWidget {
S.of(context).placeholder_transactions,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).primaryTextTheme.overline!.decorationColor!),
color: Theme.of(context).primaryTextTheme!.labelSmall!.decorationColor!),
),
);
}))

View file

@ -67,7 +67,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
return WillPopScope(
onWillPop: () async => false,
child: Container(
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
child: Column(
children: <Widget>[
SizedBox(height: 10.0),
@ -89,7 +89,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.titleLarge!
.color!),
),
)
@ -109,7 +109,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.titleLarge!
.color!),
),
)
@ -128,7 +128,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontWeight: FontWeight.normal,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.titleLarge!
.color!),
))
],
@ -148,7 +148,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.titleLarge!
.color!),
),
)
@ -195,7 +195,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
Theme.of(context)
.backgroundColor
.withOpacity(0.0),
Theme.of(context).backgroundColor,
Theme.of(context).colorScheme.background,
],
begin: FractionalOffset.topCenter,
end: FractionalOffset.bottomCenter,
@ -234,12 +234,12 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
border: Border.all(
color: Theme.of(context)
.primaryTextTheme!
.caption!
.bodySmall!
.color!,
width: 1.0),
borderRadius: BorderRadius.all(
Radius.circular(8.0)),
color: Theme.of(context).backgroundColor),
color: Theme.of(context).colorScheme.background),
child: _checked
? Icon(
Icons.check,
@ -255,7 +255,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontSize: 14.0,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.titleLarge!
.color!),
)
],
@ -275,11 +275,11 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
text: 'Accept',
color: Theme.of(context)
.accentTextTheme!
.subtitle2!
.titleSmall!
.decorationColor!,
textColor: Theme.of(context)
.accentTextTheme!
.headline5!
.headlineSmall!
.decorationColor!),
),
],

View file

@ -2,6 +2,7 @@ import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/desktop_exchange_cards_section.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/mobile_exchange_cards_section.dart';
import 'package:cake_wallet/src/widgets/add_template_button.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/debounce.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/sync_status.dart';
@ -108,23 +109,49 @@ class ExchangePage extends BasePage {
});
@override
bool get canUseCloseIcon => true;
Widget? leading(BuildContext context) {
final _backButton = Icon(Icons.arrow_back_ios,
color: titleColor,
size: 16,
);
final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme : closeButtonImage;
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile(context);
return MergeSemantics(
child: SizedBox(
height: isMobileView ? 37 : 45,
width: isMobileView ? 37 : 45,
child: ButtonTheme(
minWidth: double.minPositive,
child: Semantics(
label: !isMobileView ? 'Close' : 'Back',
child: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateColor.resolveWith(
(states) => Colors.transparent),
),
onPressed: () => onClose(context),
child: !isMobileView ? _closeButton : _backButton,
),
),
),
),
);
}
@override
Widget body(BuildContext context) {
WidgetsBinding.instance
.addPostFrameCallback((_) => _setReactions(context, exchangeViewModel));
if (exchangeViewModel.isLowFee) {
_showFeeAlert(context);
}
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:
Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
Theme.of(context).accentTextTheme!.bodyLarge!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@ -135,7 +162,7 @@ class ExchangePage extends BasePage {
toolbarButtons: [(_) => KeyboardDoneButton()])
]),
child: Container(
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
child: Form(
key: _formKey,
child: ScrollableWithBottomSection(
@ -182,7 +209,7 @@ class ExchangePage extends BasePage {
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme!
.headline1!
.displayLarge!
.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 12),
@ -216,7 +243,7 @@ class ExchangePage extends BasePage {
}
}
},
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
textColor: Colors.white,
isDisabled: exchangeViewModel.selectedProviders.isEmpty,
isLoading: exchangeViewModel.tradeState is TradeIsCreating)),
@ -253,8 +280,8 @@ class ExchangePage extends BasePage {
return TemplateTile(
key: UniqueKey(),
amount: template.amount,
from: template.depositCurrency,
to: template.receiveCurrency,
from: template.depositCurrencyTitle,
to: template.receiveCurrencyTitle,
onTap: () {
applyTemplate(context, exchangeViewModel, template);
},
@ -319,6 +346,10 @@ class ExchangePage extends BasePage {
return;
}
if (exchangeViewModel.isLowFee) {
_showFeeAlert(context);
}
final depositAddressController = depositKey.currentState!.addressController;
final depositAmountController = depositKey.currentState!.amountController;
final receiveAddressController = receiveKey.currentState!.addressController;
@ -456,8 +487,7 @@ class ExchangePage extends BasePage {
depositAmountController.addListener(() {
if (depositAmountController.text != exchangeViewModel.depositAmount) {
_depositAmountDebounce.run(() {
exchangeViewModel.changeDepositAmount(
amount: depositAmountController.text);
exchangeViewModel.changeDepositAmount(amount: depositAmountController.text);
exchangeViewModel.isReceiveAmountEntered = false;
});
}
@ -469,8 +499,7 @@ class ExchangePage extends BasePage {
receiveAmountController.addListener(() {
if (receiveAmountController.text != exchangeViewModel.receiveAmount) {
_receiveAmountDebounce.run(() {
exchangeViewModel.changeReceiveAmount(
amount: receiveAmountController.text);
exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text);
exchangeViewModel.isReceiveAmountEntered = true;
});
}
@ -625,9 +654,17 @@ class ExchangePage extends BasePage {
imageArrow: arrowBottomPurple,
currencyButtonColor: Colors.transparent,
addressButtonsColor: Theme.of(context).focusColor!,
borderColor: Theme.of(context).primaryTextTheme!.bodyText1!.color!,
currencyValueValidator:
AmountValidator(currency: exchangeViewModel.depositCurrency),
borderColor: Theme.of(context).primaryTextTheme!.bodyLarge!.color!,
currencyValueValidator: (value) {
return !exchangeViewModel.isFixedRateMode
? AmountValidator(
isAutovalidate: true,
currency: exchangeViewModel.depositCurrency,
minValue: exchangeViewModel.limits.min.toString(),
maxValue: exchangeViewModel.limits.max.toString(),
).call(value)
: null;
},
addressTextFieldValidator:
AddressValidator(type: exchangeViewModel.depositCurrency),
onPushPasteButton: (context) async {
@ -667,9 +704,17 @@ class ExchangePage extends BasePage {
currencyButtonColor: Colors.transparent,
addressButtonsColor: Theme.of(context).focusColor!,
borderColor:
Theme.of(context).primaryTextTheme!.bodyText1!.decorationColor!,
currencyValueValidator:
AmountValidator(currency: exchangeViewModel.receiveCurrency),
Theme.of(context).primaryTextTheme!.bodyLarge!.decorationColor!,
currencyValueValidator: (value) {
return exchangeViewModel.isFixedRateMode
? AmountValidator(
isAutovalidate: true,
currency: exchangeViewModel.receiveCurrency,
minValue: exchangeViewModel.limits.min.toString(),
maxValue: exchangeViewModel.limits.max.toString(),
).call(value)
: null;
},
addressTextFieldValidator:
AddressValidator(type: exchangeViewModel.receiveCurrency),
onPushPasteButton: (context) async {

View file

@ -73,8 +73,10 @@ class ExchangeTemplatePage extends BasePage {
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:
Theme.of(context).accentTextTheme.bodyText1!.backgroundColor!,
keyboardBarColor: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@ -85,7 +87,7 @@ class ExchangeTemplatePage extends BasePage {
toolbarButtons: [(_) => KeyboardDoneButton()])
]),
child: Container(
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
child: Form(
key: _formKey,
child: ScrollableWithBottomSection(
@ -99,8 +101,8 @@ class ExchangeTemplatePage extends BasePage {
),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.bodyText2!.color!,
Theme.of(context).primaryTextTheme.bodyText2!.decorationColor!,
Theme.of(context).primaryTextTheme!.bodyMedium!.color!,
Theme.of(context).primaryTextTheme!.bodyMedium!.decorationColor!,
],
stops: [0.35, 1.0],
begin: Alignment.topLeft,
@ -119,10 +121,10 @@ class ExchangeTemplatePage extends BasePage {
gradient: LinearGradient(
colors: [
Theme.of(context)
.primaryTextTheme.subtitle2!
.primaryTextTheme!.titleSmall!
.color!,
Theme.of(context)
.primaryTextTheme.subtitle2!
.primaryTextTheme!.titleSmall!
.decorationColor!,
],
begin: Alignment.topLeft,
@ -157,7 +159,7 @@ class ExchangeTemplatePage extends BasePage {
addressButtonsColor:
Theme.of(context).focusColor,
borderColor: Theme.of(context)
.primaryTextTheme.bodyText1!
.primaryTextTheme!.bodyLarge!
.color!,
currencyValueValidator: AmountValidator(
currency: exchangeViewModel.depositCurrency),
@ -197,7 +199,7 @@ class ExchangeTemplatePage extends BasePage {
addressButtonsColor:
Theme.of(context).focusColor,
borderColor: Theme.of(context)
.primaryTextTheme.bodyText1!
.primaryTextTheme!.bodyLarge!
.decorationColor!,
currencyValueValidator: AmountValidator(
currency: exchangeViewModel.receiveCurrency),
@ -225,7 +227,7 @@ class ExchangeTemplatePage extends BasePage {
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme.headline1!
.primaryTextTheme!.displayLarge!
.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 12),
@ -239,9 +241,13 @@ class ExchangeTemplatePage extends BasePage {
exchangeViewModel.addTemplate(
amount: exchangeViewModel.depositAmount,
depositCurrency:
exchangeViewModel.depositCurrency.toString(),
exchangeViewModel.depositCurrency.name,
depositCurrencyTitle: exchangeViewModel
.depositCurrency.title + ' ${exchangeViewModel.depositCurrency.tag ?? ''}',
receiveCurrency:
exchangeViewModel.receiveCurrency.toString(),
exchangeViewModel.receiveCurrency.name,
receiveCurrencyTitle: exchangeViewModel
.receiveCurrency.title + ' ${exchangeViewModel.receiveCurrency.tag ?? ''}',
provider: exchangeViewModel.provider.toString(),
depositAddress: exchangeViewModel.depositAddress,
receiveAddress: exchangeViewModel.receiveAddress);

View file

@ -20,7 +20,10 @@ class PickerItemWidget extends StatelessWidget {
return GestureDetector(
onTap: onTap,
child: Container(
color: Theme.of(context).accentTextTheme!.headline6!.color!,
color: Theme.of(context)
.accentTextTheme!
.titleLarge!
.color!,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
child: Row(
@ -39,7 +42,12 @@ class PickerItemWidget extends StatelessWidget {
Text(
title.toUpperCase(),
style: TextStyle(
color: isSelected ? Palette.blueCraiola : Theme.of(context).primaryTextTheme!.headline6!.color!,
color: isSelected
? Palette.blueCraiola
: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!,
fontSize: isSelected ? 16 : 14.0,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
@ -55,20 +63,33 @@ class PickerItemWidget extends StatelessWidget {
child: Text(
tag!,
style: TextStyle(
fontSize: 7.0, fontFamily: 'Lato', color: Theme.of(context).textTheme!.bodyText2!.color!),
fontSize: 7.0,
fontFamily: 'Lato',
color: Theme.of(context)
.textTheme!
.bodyMedium!
.color!),
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
//border: Border.all(color: ),
color: Theme.of(context).textTheme!.bodyText2!.decorationColor!,
color: Theme.of(context)
.textTheme!
.bodyMedium!
.decorationColor!,
),
),
),
],
),
),
if (isSelected) Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme!.bodyText1!.color!)
if (isSelected)
Icon(Icons.check_circle,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!)
],
),
),

View file

@ -20,7 +20,10 @@ class CurrencyPickerWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.titleLarge!
.backgroundColor!,
child: Scrollbar(
controller: _scrollController,
child: GridView.builder(

View file

@ -160,7 +160,7 @@ class ExchangeCardState extends State<ExchangeCard> {
final copyImage = Image.asset('assets/images/copy_content.png',
height: 16,
width: 16,
color: Theme.of(context).primaryTextTheme.headline3!.color!);
color: Theme.of(context).primaryTextTheme!.displaySmall!.color!);
return Container(
width: double.infinity,
@ -175,7 +175,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme.headline5!.color!),
color: Theme.of(context).textTheme!.headlineSmall!.color!),
)
],
),
@ -210,7 +210,11 @@ class ExchangeCardState extends State<ExchangeCard> {
child: Container(
height: 32,
decoration: BoxDecoration(
color: widget.addressButtonsColor ?? Theme.of(context).primaryTextTheme.headline4!.color!,
color: widget.addressButtonsColor ??
Theme.of(context)
.primaryTextTheme!
.headlineMedium!
.color!,
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: Center(
@ -221,7 +225,8 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme.headline4!
.primaryTextTheme!
.headlineMedium!
.decorationColor!)),
),
),
@ -264,7 +269,8 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme.headline1!
.accentTextTheme!
.displayLarge!
.decorationColor!),
validator: _isAmountEditable
? widget.currencyValueValidator
@ -277,7 +283,8 @@ class ExchangeCardState extends State<ExchangeCard> {
width: 32,
decoration: BoxDecoration(
color: Theme.of(context)
.primaryTextTheme.headline4!
.primaryTextTheme!
.headlineMedium!
.color!,
borderRadius:
BorderRadius.all(Radius.circular(6))),
@ -290,7 +297,8 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme.headline4!
.primaryTextTheme!
.headlineMedium!
.decorationColor!)),
),
),
@ -300,9 +308,12 @@ class ExchangeCardState extends State<ExchangeCard> {
),
],
)),
Divider(height: 1,color: Theme.of(context)
.primaryTextTheme.headline5!
.decorationColor!),
Divider(
height: 1,
color: Theme.of(context)
.primaryTextTheme!
.headlineSmall!
.decorationColor!),
Padding(
padding: EdgeInsets.only(top: 5),
child: Container(
@ -319,7 +330,8 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme.headline1!
.accentTextTheme!
.displayLarge!
.decorationColor!),
)
: Offstage(),
@ -333,7 +345,8 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme.headline1!
.accentTextTheme!
.displayLarge!
.decorationColor!))
: Offstage(),
])),
@ -347,7 +360,8 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme.headline1!
.accentTextTheme!
.displayLarge!
.decorationColor!),
))
: Offstage(),
@ -387,7 +401,8 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme.headline1!
.accentTextTheme!
.displayLarge!
.decorationColor!),
buttonColor: widget.addressButtonsColor,
validator: widget.addressTextFieldValidator,
@ -406,7 +421,6 @@ class ExchangeCardState extends State<ExchangeCard> {
order: NumericFocusOrder(3),
child: BaseTextFormField(
controller: addressController,
readOnly: true,
borderColor: Colors.transparent,
suffixIcon:
SizedBox(width: _isMoneroWallet ? 80 : 36),
@ -433,7 +447,10 @@ class ExchangeCardState extends State<ExchangeCard> {
onTap: () async {
final contact =
await Navigator.of(context)
.pushNamed(Routes.pickerAddressBook);
.pushNamed(
Routes.pickerAddressBook,
arguments: widget.initialCurrency,
);
if (contact is ContactBase &&
contact.address != null) {
@ -456,7 +473,8 @@ class ExchangeCardState extends State<ExchangeCard> {
child: Image.asset(
'assets/images/open_book.png',
color: Theme.of(context)
.primaryTextTheme.headline4!
.primaryTextTheme!
.headlineMedium!
.decorationColor!,
)),
)),

View file

@ -21,8 +21,8 @@ class MobileExchangeCardsSection extends StatelessWidget {
),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.bodyText2!.color!,
Theme.of(context).primaryTextTheme.bodyText2!.decorationColor!,
Theme.of(context).primaryTextTheme!.bodyMedium!.color!,
Theme.of(context).primaryTextTheme!.bodyMedium!.decorationColor!,
],
stops: [0.35, 1.0],
begin: Alignment.topLeft,
@ -37,8 +37,11 @@ class MobileExchangeCardsSection extends StatelessWidget {
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.subtitle2!.color!,
Theme.of(context).primaryTextTheme.subtitle2!.decorationColor!,
Theme.of(context).primaryTextTheme!.titleSmall!.color!,
Theme.of(context)
.primaryTextTheme!
.titleSmall!
.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,

View file

@ -49,7 +49,10 @@ class PresentProviderPicker extends StatelessWidget {
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.headline5!.color!)))
color: Theme.of(context)
.textTheme!
.headlineSmall!
.color!)))
],
),
SizedBox(width: 5),

View file

@ -36,7 +36,10 @@ class ExchangeConfirmPage extends BasePage {
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
color: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!),
),
)),
Container(
@ -45,8 +48,14 @@ class ExchangeConfirmPage extends BasePage {
borderRadius: BorderRadius.all(Radius.circular(30)),
border: Border.all(
width: 1,
color: Theme.of(context).accentTextTheme!.caption!.color!),
color: Theme.of(context).accentTextTheme!.headline6!.color!),
color: Theme.of(context)
.accentTextTheme!
.bodySmall!
.color!),
color: Theme.of(context)
.accentTextTheme!
.titleLarge!
.color!),
child: Column(
children: <Widget>[
Expanded(
@ -63,7 +72,7 @@ class ExchangeConfirmPage extends BasePage {
fontWeight: FontWeight.w500,
color: Theme.of(context)
.primaryTextTheme!
.overline!
.labelSmall!
.color!),
),
Text(
@ -75,7 +84,7 @@ class ExchangeConfirmPage extends BasePage {
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.titleLarge!
.color!),
),
],
@ -93,10 +102,12 @@ class ExchangeConfirmPage extends BasePage {
text: S.of(context).copy_id,
color: Theme.of(context)
.accentTextTheme!
.caption!
.bodySmall!
.backgroundColor!,
textColor:
Theme.of(context).primaryTextTheme!.headline6!.color!),
textColor: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!),
),
)
],
@ -125,7 +136,10 @@ class ExchangeConfirmPage extends BasePage {
onPressed: () => Navigator.of(context)
.pushReplacementNamed(Routes.exchangeTrade),
text: S.of(context).saved_the_trade_id,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white)
],
),

View file

@ -51,7 +51,7 @@ class ExchangeTradePage extends BasePage {
@override
Widget trailing(BuildContext context) {
final questionImage = Image.asset('assets/images/question_mark.png',
color: Theme.of(context).primaryTextTheme!.headline6!.color!);
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!);
return SizedBox(
height: 20.0,
@ -111,7 +111,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
final copyImage = Image.asset('assets/images/copy_content.png',
height: 16,
width: 16,
color: Theme.of(context).primaryTextTheme!.overline!.color!);
color: Theme.of(context).primaryTextTheme!.labelSmall!.color!);
_setEffects();
@ -135,14 +135,14 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
fontWeight: FontWeight.w500,
color: Theme.of(context)
.primaryTextTheme!
.overline!
.labelSmall!
.color!),
),
if (trade.expiredAt != null)
TimerWidget(trade.expiredAt!,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.titleLarge!
.color!)
])
: Offstage(),
@ -162,7 +162,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
width: 3,
color: Theme.of(context)
.accentTextTheme!
.subtitle2!
.titleSmall!
.color!
)
),
@ -181,7 +181,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
height: 1,
color: Theme.of(context)
.accentTextTheme!
.subtitle2!
.titleSmall!
.backgroundColor!,
),
itemBuilder: (context, index) {
@ -228,7 +228,10 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
onPressed: () =>
widget.exchangeTradeViewModel.confirmSending(),
text: S.of(context).confirm,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white)
: Offstage();
})),
@ -340,7 +343,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
fontWeight: FontWeight.bold,
color: Theme.of(popupContext)
.primaryTextTheme!
.headline6!
.titleLarge!
.color,
decoration: TextDecoration.none,
),
@ -359,7 +362,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
text: S.of(popupContext).send_got_it,
color: Theme.of(popupContext)
.accentTextTheme!
.bodyText1!
.bodyLarge!
.color!,
textColor: Colors.white))
],
@ -392,7 +395,10 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Theme.of(popupContext).primaryTextTheme!.headline6!.color!,
color: Theme.of(popupContext)
.primaryTextTheme!
.titleLarge!
.color!,
decoration: TextDecoration.none,
),
),

View file

@ -21,7 +21,7 @@ class InformationPage extends StatelessWidget {
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30)),
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!
color: Theme.of(context).textTheme!.bodyLarge!.decorationColor!
),
child: Column(
mainAxisSize: MainAxisSize.min,
@ -35,7 +35,7 @@ class InformationPage extends StatelessWidget {
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color: Theme.of(context).accentTextTheme!.caption!.decorationColor!
color: Theme.of(context).accentTextTheme!.bodySmall!.decorationColor!
),
),
),
@ -44,8 +44,8 @@ class InformationPage extends StatelessWidget {
child: PrimaryButton(
onPressed: () => Navigator.of(context).pop(),
text: S.of(context).send_got_it,
color: Theme.of(context).accentTextTheme!.caption!.backgroundColor!,
textColor: Theme.of(context).primaryTextTheme!.headline6!.color!
color: Theme.of(context).accentTextTheme!.bodySmall!.backgroundColor!,
textColor: Theme.of(context).primaryTextTheme!.titleLarge!.color!
),
)
],

View file

@ -25,13 +25,13 @@ class FAQItemState extends State<FAQItem> {
@override
Widget build(BuildContext context) {
final addIcon =
Icon(Icons.add, color: Theme.of(context).primaryTextTheme!.headline6!.color!);
final addIcon = Icon(Icons.add,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!);
final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola);
final icon = isActive ? removeIcon : addIcon;
final color = isActive
? Palette.blueCraiola
: Theme.of(context).primaryTextTheme!.headline6!.color!;
: Theme.of(context).primaryTextTheme!.titleLarge!.color!;
return ListTileTheme(
contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6),
@ -53,7 +53,8 @@ class FAQItemState extends State<FAQItem> {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
color:
Theme.of(context).primaryTextTheme!.titleLarge!.color!),
),
))
])

View file

@ -40,7 +40,10 @@ class IoniaCreateAccountPage extends BasePage {
return Text(
S.current.sign_up,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!,
),
);
}
@ -79,8 +82,12 @@ class IoniaCreateAccountPage extends BasePage {
builder: (_) => LoadingPrimaryButton(
text: S.of(context).create_account,
onPressed: _createAccount,
isLoading: _authViewModel.createUserState is IoniaCreateStateLoading,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
isLoading:
_authViewModel.createUserState is IoniaCreateStateLoading,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white,
),
),
@ -100,7 +107,10 @@ class IoniaCreateAccountPage extends BasePage {
TextSpan(
text: S.of(context).settings_terms_and_conditions,
style: TextStyle(
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()
@ -112,7 +122,10 @@ class IoniaCreateAccountPage extends BasePage {
TextSpan(
text: S.of(context).privacy_policy,
style: TextStyle(
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()

View file

@ -33,7 +33,10 @@ class IoniaLoginPage extends BasePage {
return Text(
S.current.login,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!,
),
);
}
@ -71,7 +74,10 @@ class IoniaLoginPage extends BasePage {
text: S.of(context).login,
onPressed: _login,
isLoading: _authViewModel.signInState is IoniaCreateStateLoading,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white,
),
),

View file

@ -41,7 +41,10 @@ class IoniaVerifyIoniaOtp extends BasePage {
return Text(
S.current.verification,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!,
),
);
}
@ -62,7 +65,10 @@ class IoniaVerifyIoniaOtp extends BasePage {
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
keyboardBarColor: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@ -72,7 +78,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
]),
child: Container(
height: 0,
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Column(
@ -93,7 +99,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(S.of(context).dont_get_code),
Text(S.of(context).didnt_get_code),
SizedBox(width: 20),
InkWell(
onTap: () => isSignIn
@ -120,7 +126,10 @@ class IoniaVerifyIoniaOtp extends BasePage {
onPressed: _verify,
isDisabled: _authViewModel.otpState is IoniaOtpSendDisabled,
isLoading: _authViewModel.otpState is IoniaOtpValidating,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white,
),
),

View file

@ -17,7 +17,10 @@ class IoniaWelcomePage extends BasePage {
return Text(
S.current.welcome_to_cakepay,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!,
),
);
}
@ -45,7 +48,7 @@ class IoniaWelcomePage extends BasePage {
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
),
),
SizedBox(height: 20),
@ -55,7 +58,7 @@ class IoniaWelcomePage extends BasePage {
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
),
),
],
@ -66,7 +69,10 @@ class IoniaWelcomePage extends BasePage {
PrimaryButton(
text: S.of(context).create_account,
onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaCreateAccountPage),
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
textColor: Colors.white,
),
SizedBox(
@ -78,7 +84,7 @@ class IoniaWelcomePage extends BasePage {
fontSize: 15,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
),
),
SizedBox(height: 8),

View file

@ -20,7 +20,10 @@ class IoniaAccountCardsPage extends BasePage {
return Text(
S.of(context).cards,
style: textLargeSemiBold(
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
color: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!,
),
);
}
@ -69,23 +72,34 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
width: 230,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
color: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!
.withOpacity(0.1),
borderRadius: BorderRadius.circular(
25.0,
),
),
child: Theme(
data: ThemeData(primaryTextTheme: TextTheme(bodyText1: TextStyle(backgroundColor: Colors.transparent))),
data: ThemeData(primaryTextTheme: TextTheme(bodyLarge: TextStyle(backgroundColor: Colors.transparent))),
child: TabBar(
controller: _tabController,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(
25.0,
),
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
color: Theme.of(context)
.accentTextTheme!
.bodyLarge!
.color!,
),
labelColor: Theme.of(context).primaryTextTheme!.headline1!.backgroundColor!,
unselectedLabelColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
labelColor: Theme.of(context)
.primaryTextTheme!
.displayLarge!
.backgroundColor!,
unselectedLabelColor:
Theme.of(context).primaryTextTheme!.titleLarge!.color!,
tabs: [
Tab(
text: S.of(context).active,
@ -154,9 +168,13 @@ class _IoniaCardListView extends StatelessWidget {
Widget build(BuildContext context) {
if(isLoading){
return Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryTextTheme!.bodyText2!.color!),
child: CircularProgressIndicator(
backgroundColor: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).primaryTextTheme!.bodyMedium!.color!),
),
);
}
@ -166,7 +184,7 @@ class _IoniaCardListView extends StatelessWidget {
emptyText,
textAlign: TextAlign.center,
style: textSmall(
color: Theme.of(context).primaryTextTheme!.overline!.color!,
color: Theme.of(context).primaryTextTheme!.labelSmall!.color!,
),
),
)
@ -179,11 +197,18 @@ class _IoniaCardListView extends StatelessWidget {
child: CardItem(
onTap: () => onTap?.call(merchant),
title: merchant.legalName,
backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
backgroundColor: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!
.withOpacity(0.1),
discount: 0,
hideBorder: true,
discountBackground: AssetImage('assets/images/red_badge_discount.png'),
titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
titleColor: Theme.of(context)
.accentTextTheme!
.displayLarge!
.backgroundColor!,
subtitleColor: Theme.of(context).hintColor,
subTitle: '',
logoUrl: merchant.logoUrl,

Some files were not shown because too many files have changed in this diff Show more