mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
Merge branch 'main' into CW-432-Add-Bitcoin-Cash-BCH
This commit is contained in:
commit
f7470addfe
322 changed files with 6381 additions and 4217 deletions
2
.github/workflows/cache_dependencies.yml
vendored
2
.github/workflows/cache_dependencies.yml
vendored
|
@ -18,7 +18,7 @@ jobs:
|
|||
- name: Flutter action
|
||||
uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: '3.3.x'
|
||||
flutter-version: '3.10.x'
|
||||
channel: stable
|
||||
|
||||
- name: Install package dependencies
|
||||
|
|
4
.github/workflows/pr_test_build.yml
vendored
4
.github/workflows/pr_test_build.yml
vendored
|
@ -28,7 +28,7 @@ jobs:
|
|||
- name: Flutter action
|
||||
uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: '3.7.x'
|
||||
flutter-version: '3.10.x'
|
||||
channel: stable
|
||||
|
||||
- name: Install package dependencies
|
||||
|
@ -55,7 +55,7 @@ jobs:
|
|||
/opt/android/cake_wallet/cw_monero/android/.cxx
|
||||
/opt/android/cake_wallet/cw_monero/ios/External
|
||||
/opt/android/cake_wallet/cw_shared_external/ios/External
|
||||
key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh') }}
|
||||
key: ${{ hashFiles('**/build_monero.sh', '**/build_haven.sh', '**/monero_api.cpp') }}
|
||||
|
||||
- if: ${{ steps.cache-externals.outputs.cache-hit != 'true' }}
|
||||
name: Generate Externals
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -144,4 +144,4 @@ assets/images/app_logo.png
|
|||
|
||||
macos/Runner/Info.plist
|
||||
macos/Runner/DebugProfile.entitlements
|
||||
macos/Runner/Release.entitlements
|
||||
macos/Runner/Release.entitlements
|
||||
|
|
|
@ -27,6 +27,6 @@ subprojects {
|
|||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
|
@ -1,8 +1,2 @@
|
|||
Monero background syncing! See https://guides.cakewallet.com/docs/monero/#background-syncing
|
||||
Cake 2FA access control settings! See https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa-presets-and-access-control-settings
|
||||
Support Monero node proxy
|
||||
UI improvements when sending to Address Book entry
|
||||
Allow renaming Monero account names
|
||||
Send templates now support multiple recipients (try using to make Monero change)
|
||||
Onramper improvements
|
||||
Scan node QR codes (for Umbrel)
|
||||
Bug fixes
|
||||
Fiat Onramp improvements
|
|
@ -1,9 +1,2 @@
|
|||
Ethereum! Store ETH and ERC-20 tokens
|
||||
Monero background syncing! See https://guides.cakewallet.com/docs/monero/#background-syncing
|
||||
Cake 2FA access control settings! See https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa-presets-and-access-control-settings
|
||||
Support Monero node proxy
|
||||
UI improvements when sending to Address Book entry
|
||||
Allow renaming Monero/Haven account names
|
||||
Send templates now support multiple recipients (try using to make Monero change)
|
||||
Onramper improvements
|
||||
Scan node QR codes (for Umbrel)
|
||||
Bug fixes
|
||||
Fiat Onramp improvements
|
|
@ -1,4 +1,4 @@
|
|||
class BitcoinTransactionNoInputsException implements Exception {
|
||||
@override
|
||||
String toString() => 'Not enough inputs available';
|
||||
String toString() => 'Not enough inputs available. Please select more under Coin Control';
|
||||
}
|
||||
|
|
|
@ -755,5 +755,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <4.0.0"
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -13,16 +13,16 @@ dependencies:
|
|||
flutter:
|
||||
sdk: flutter
|
||||
path_provider: ^2.0.11
|
||||
http: ^0.13.4
|
||||
http: ^1.1.0
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
intl: ^0.18.0
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
bitcoin_flutter:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_flutter.git
|
||||
ref: cake-update-v2
|
||||
ref: cake-update-v3
|
||||
bitbox:
|
||||
git:
|
||||
url: https://github.com/Serhii-Borodenko/cw_bitbox.git
|
||||
|
|
|
@ -2,24 +2,31 @@ import 'package:cw_core/balance.dart';
|
|||
import 'package:cw_core/monero_amount_format.dart';
|
||||
|
||||
class MoneroBalance extends Balance {
|
||||
MoneroBalance({required this.fullBalance, required this.unlockedBalance})
|
||||
MoneroBalance({required this.fullBalance, required this.unlockedBalance, this.frozenBalance = 0})
|
||||
: formattedFullBalance = moneroAmountToString(amount: fullBalance),
|
||||
formattedUnlockedBalance =
|
||||
moneroAmountToString(amount: unlockedBalance),
|
||||
formattedUnlockedBalance = moneroAmountToString(amount: unlockedBalance),
|
||||
frozenFormatted = moneroAmountToString(amount: frozenBalance),
|
||||
super(unlockedBalance, fullBalance);
|
||||
|
||||
MoneroBalance.fromString(
|
||||
{required this.formattedFullBalance,
|
||||
required this.formattedUnlockedBalance})
|
||||
required this.formattedUnlockedBalance,
|
||||
this.frozenFormatted = '0.0'})
|
||||
: fullBalance = moneroParseAmount(amount: formattedFullBalance),
|
||||
unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
|
||||
frozenBalance = moneroParseAmount(amount: frozenFormatted),
|
||||
super(moneroParseAmount(amount: formattedUnlockedBalance),
|
||||
moneroParseAmount(amount: formattedFullBalance));
|
||||
|
||||
final int fullBalance;
|
||||
final int unlockedBalance;
|
||||
final int frozenBalance;
|
||||
final String formattedFullBalance;
|
||||
final String formattedUnlockedBalance;
|
||||
final String frozenFormatted;
|
||||
|
||||
@override
|
||||
String get formattedFrozenBalance => frozenFormatted == '0.0' ? '' : frozenFormatted;
|
||||
|
||||
@override
|
||||
String get formattedAvailableBalance => formattedUnlockedBalance;
|
||||
|
|
|
@ -13,7 +13,9 @@ class UnspentCoinsInfo extends HiveObject {
|
|||
required this.noteRaw,
|
||||
required this.address,
|
||||
required this.vout,
|
||||
required this.value});
|
||||
required this.value,
|
||||
this.keyImage = null
|
||||
});
|
||||
|
||||
static const typeId = UNSPENT_COINS_INFO_TYPE_ID;
|
||||
static const boxName = 'Unspent';
|
||||
|
@ -43,6 +45,9 @@ class UnspentCoinsInfo extends HiveObject {
|
|||
@HiveField(7, defaultValue: 0)
|
||||
int vout;
|
||||
|
||||
@HiveField(8, defaultValue: null)
|
||||
String? keyImage;
|
||||
|
||||
String get note => noteRaw ?? '';
|
||||
|
||||
set note(String value) => noteRaw = value;
|
||||
|
|
|
@ -42,7 +42,9 @@ abstract class WalletBase<
|
|||
|
||||
set syncStatus(SyncStatus status);
|
||||
|
||||
String get seed;
|
||||
String? get seed;
|
||||
|
||||
String? get privateKey => null;
|
||||
|
||||
Object get keys;
|
||||
|
||||
|
|
|
@ -665,5 +665,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <4.0.0"
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -12,12 +12,12 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
http: ^0.13.4
|
||||
http: ^1.1.0
|
||||
file: ^6.1.4
|
||||
path_provider: ^2.0.11
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
intl: ^0.18.0
|
||||
encrypt: ^5.0.1
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:cw_ethereum/pending_ethereum_transaction.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:web3dart/web3dart.dart';
|
||||
import 'package:web3dart/contracts/erc20.dart';
|
||||
import 'package:erc20/erc20.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_ethereum/ethereum_transaction_priority.dart';
|
||||
import 'package:cw_ethereum/.secrets.g.dart' as secrets;
|
||||
|
@ -72,7 +72,7 @@ class EthereumClient {
|
|||
to: EthereumAddress.fromHex(toAddress),
|
||||
maxGas: gas,
|
||||
gasPrice: price,
|
||||
maxPriorityFeePerGas: EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip),
|
||||
maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
|
||||
value: _isEthereum ? EtherAmount.inWei(BigInt.parse(amount)) : EtherAmount.zero(),
|
||||
);
|
||||
|
||||
|
@ -83,7 +83,7 @@ class EthereumClient {
|
|||
if (_isEthereum) {
|
||||
_sendTransaction = () async => await sendTransaction(signedTransaction);
|
||||
} else {
|
||||
final erc20 = Erc20(
|
||||
final erc20 = ERC20(
|
||||
client: _client!,
|
||||
address: EthereumAddress.fromHex(contractAddress!),
|
||||
);
|
||||
|
@ -153,7 +153,7 @@ I/flutter ( 4474): Gas Used: 53000
|
|||
|
||||
Future<ERC20Balance> fetchERC20Balances(
|
||||
EthereumAddress userAddress, String contractAddress) async {
|
||||
final erc20 = Erc20(address: EthereumAddress.fromHex(contractAddress), client: _client!);
|
||||
final erc20 = ERC20(address: EthereumAddress.fromHex(contractAddress), client: _client!);
|
||||
final balance = await erc20.balanceOf(userAddress);
|
||||
|
||||
int exponent = (await erc20.decimals()).toInt();
|
||||
|
@ -163,7 +163,7 @@ I/flutter ( 4474): Gas Used: 53000
|
|||
|
||||
Future<Erc20Token?> getErc20Token(String contractAddress) async {
|
||||
try {
|
||||
final erc20 = Erc20(address: EthereumAddress.fromHex(contractAddress), client: _client!);
|
||||
final erc20 = ERC20(address: EthereumAddress.fromHex(contractAddress), client: _client!);
|
||||
final name = await erc20.name();
|
||||
final symbol = await erc20.symbol();
|
||||
final decimal = await erc20.decimals();
|
||||
|
|
|
@ -44,12 +44,14 @@ abstract class EthereumWalletBase
|
|||
with Store {
|
||||
EthereumWalletBase({
|
||||
required WalletInfo walletInfo,
|
||||
required String mnemonic,
|
||||
String? mnemonic,
|
||||
String? privateKey,
|
||||
required String password,
|
||||
ERC20Balance? initialBalance,
|
||||
}) : syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
_mnemonic = mnemonic,
|
||||
_hexPrivateKey = privateKey,
|
||||
_isTransactionUpdating = false,
|
||||
_client = EthereumClient(),
|
||||
walletAddresses = EthereumWalletAddresses(walletInfo),
|
||||
|
@ -66,12 +68,13 @@ abstract class EthereumWalletBase
|
|||
_sharedPrefs.complete(SharedPreferences.getInstance());
|
||||
}
|
||||
|
||||
final String _mnemonic;
|
||||
final String? _mnemonic;
|
||||
final String? _hexPrivateKey;
|
||||
final String _password;
|
||||
|
||||
late final Box<Erc20Token> erc20TokensBox;
|
||||
|
||||
late final EthPrivateKey _privateKey;
|
||||
late final EthPrivateKey _ethPrivateKey;
|
||||
|
||||
late EthereumClient _client;
|
||||
|
||||
|
@ -99,8 +102,12 @@ abstract class EthereumWalletBase
|
|||
erc20TokensBox = await CakeHive.openBox<Erc20Token>(Erc20Token.boxName);
|
||||
await walletAddresses.init();
|
||||
await transactionHistory.init();
|
||||
_privateKey = await getPrivateKey(_mnemonic, _password);
|
||||
walletAddresses.address = _privateKey.address.toString();
|
||||
_ethPrivateKey = await getPrivateKey(
|
||||
mnemonic: _mnemonic,
|
||||
privateKey: _hexPrivateKey,
|
||||
password: _password,
|
||||
);
|
||||
walletAddresses.address = _ethPrivateKey.address.toString();
|
||||
await save();
|
||||
}
|
||||
|
||||
|
@ -108,8 +115,7 @@ abstract class EthereumWalletBase
|
|||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||
try {
|
||||
if (priority is EthereumTransactionPriority) {
|
||||
final priorityFee =
|
||||
EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip).getInWei.toInt();
|
||||
final priorityFee = EtherAmount.fromInt(EtherUnit.gwei, priority.tip).getInWei.toInt();
|
||||
return (_gasPrice! + priorityFee) * (_estimatedGas ?? 0);
|
||||
}
|
||||
|
||||
|
@ -142,7 +148,7 @@ abstract class EthereumWalletBase
|
|||
throw Exception("Ethereum Node connection failed");
|
||||
}
|
||||
|
||||
_client.setListeners(_privateKey.address, _onNewTransaction);
|
||||
_client.setListeners(_ethPrivateKey.address, _onNewTransaction);
|
||||
|
||||
_setTransactionUpdateTimer();
|
||||
|
||||
|
@ -202,7 +208,7 @@ abstract class EthereumWalletBase
|
|||
}
|
||||
|
||||
final pendingEthereumTransaction = await _client.signTransaction(
|
||||
privateKey: _privateKey,
|
||||
privateKey: _ethPrivateKey,
|
||||
toAddress: _credentials.outputs.first.isParsedAddress
|
||||
? _credentials.outputs.first.extractedAddress!
|
||||
: _credentials.outputs.first.address,
|
||||
|
@ -240,7 +246,7 @@ abstract class EthereumWalletBase
|
|||
|
||||
@override
|
||||
Future<Map<String, EthereumTransactionInfo>> fetchTransactions() async {
|
||||
final address = _privateKey.address.hex;
|
||||
final address = _ethPrivateKey.address.hex;
|
||||
final transactions = await _client.fetchTransactions(address);
|
||||
|
||||
final List<Future<List<EthereumTransactionModel>>> erc20TokensTransactions = [];
|
||||
|
@ -300,7 +306,10 @@ abstract class EthereumWalletBase
|
|||
}
|
||||
|
||||
@override
|
||||
String get seed => _mnemonic;
|
||||
String? get seed => _mnemonic;
|
||||
|
||||
@override
|
||||
String get privateKey => HEX.encode(_ethPrivateKey.privateKey);
|
||||
|
||||
@action
|
||||
@override
|
||||
|
@ -327,6 +336,7 @@ abstract class EthereumWalletBase
|
|||
|
||||
String toJSON() => json.encode({
|
||||
'mnemonic': _mnemonic,
|
||||
'private_key': privateKey,
|
||||
'balance': balance[currency]!.toJSON(),
|
||||
});
|
||||
|
||||
|
@ -338,13 +348,15 @@ abstract class EthereumWalletBase
|
|||
final path = await pathForWallet(name: name, type: walletInfo.type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final mnemonic = data['mnemonic'] as String;
|
||||
final mnemonic = data['mnemonic'] as String?;
|
||||
final privateKey = data['private_key'] as String?;
|
||||
final balance = ERC20Balance.fromJSON(data['balance'] as String) ?? ERC20Balance(BigInt.zero);
|
||||
|
||||
return EthereumWallet(
|
||||
walletInfo: walletInfo,
|
||||
password: password,
|
||||
mnemonic: mnemonic,
|
||||
privateKey: privateKey,
|
||||
initialBalance: balance,
|
||||
);
|
||||
}
|
||||
|
@ -357,7 +369,7 @@ abstract class EthereumWalletBase
|
|||
}
|
||||
|
||||
Future<ERC20Balance> _fetchEthBalance() async {
|
||||
final balance = await _client.getBalance(_privateKey.address);
|
||||
final balance = await _client.getBalance(_ethPrivateKey.address);
|
||||
return ERC20Balance(balance.getInWei);
|
||||
}
|
||||
|
||||
|
@ -366,7 +378,7 @@ abstract class EthereumWalletBase
|
|||
try {
|
||||
if (token.enabled) {
|
||||
balance[token] = await _client.fetchERC20Balances(
|
||||
_privateKey.address,
|
||||
_ethPrivateKey.address,
|
||||
token.contractAddress,
|
||||
);
|
||||
} else {
|
||||
|
@ -376,8 +388,15 @@ abstract class EthereumWalletBase
|
|||
}
|
||||
}
|
||||
|
||||
Future<EthPrivateKey> getPrivateKey(String mnemonic, String password) async {
|
||||
final seed = bip39.mnemonicToSeed(mnemonic);
|
||||
Future<EthPrivateKey> getPrivateKey(
|
||||
{String? mnemonic, String? privateKey, required String password}) async {
|
||||
assert(mnemonic != null || privateKey != null);
|
||||
|
||||
if (privateKey != null) {
|
||||
return EthPrivateKey.fromHex(privateKey);
|
||||
}
|
||||
|
||||
final seed = bip39.mnemonicToSeed(mnemonic!);
|
||||
|
||||
final root = bip32.BIP32.fromSeed(seed);
|
||||
|
||||
|
@ -413,7 +432,7 @@ abstract class EthereumWalletBase
|
|||
|
||||
if (_token.enabled) {
|
||||
balance[_token] = await _client.fetchERC20Balances(
|
||||
_privateKey.address,
|
||||
_ethPrivateKey.address,
|
||||
_token.contractAddress,
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -8,16 +8,22 @@ class EthereumNewWalletCredentials extends WalletCredentials {
|
|||
|
||||
class EthereumRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
EthereumRestoreWalletFromSeedCredentials(
|
||||
{required String name, required String password, required this.mnemonic, WalletInfo? walletInfo})
|
||||
{required String name,
|
||||
required String password,
|
||||
required this.mnemonic,
|
||||
WalletInfo? walletInfo})
|
||||
: super(name: name, password: password, walletInfo: walletInfo);
|
||||
|
||||
final String mnemonic;
|
||||
}
|
||||
|
||||
class EthereumRestoreWalletFromWIFCredentials extends WalletCredentials {
|
||||
EthereumRestoreWalletFromWIFCredentials(
|
||||
{required String name, required String password, required this.wif, WalletInfo? walletInfo})
|
||||
class EthereumRestoreWalletFromPrivateKey extends WalletCredentials {
|
||||
EthereumRestoreWalletFromPrivateKey(
|
||||
{required String name,
|
||||
required String password,
|
||||
required this.privateKey,
|
||||
WalletInfo? walletInfo})
|
||||
: super(name: name, password: password, walletInfo: walletInfo);
|
||||
|
||||
final String wif;
|
||||
final String privateKey;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import 'package:bip39/bip39.dart' as bip39;
|
|||
import 'package:collection/collection.dart';
|
||||
|
||||
class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
||||
EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromWIFCredentials> {
|
||||
EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromPrivateKey> {
|
||||
EthereumWalletService(this.walletInfoSource);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
|
@ -66,8 +66,18 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
|||
}
|
||||
|
||||
@override
|
||||
Future<EthereumWallet> restoreFromKeys(credentials) {
|
||||
throw UnimplementedError();
|
||||
Future<EthereumWallet> restoreFromKeys(EthereumRestoreWalletFromPrivateKey credentials) async {
|
||||
final wallet = EthereumWallet(
|
||||
password: credentials.password!,
|
||||
privateKey: credentials.privateKey,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
);
|
||||
|
||||
await wallet.init();
|
||||
wallet.addInitialTokens();
|
||||
await wallet.save();
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -12,13 +12,14 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
web3dart: 2.3.5
|
||||
web3dart: ^2.7.1
|
||||
erc20: ^1.0.1
|
||||
mobx: ^2.0.7+4
|
||||
bip39: ^1.0.6
|
||||
bip32: ^2.0.0
|
||||
ed25519_hd_key: ^2.2.0
|
||||
hex: ^0.2.0
|
||||
http: ^0.13.4
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.15
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
|
|
|
@ -13,11 +13,11 @@ dependencies:
|
|||
flutter:
|
||||
sdk: flutter
|
||||
ffi: ^2.0.1
|
||||
http: ^0.13.4
|
||||
http: ^1.1.0
|
||||
path_provider: ^2.0.11
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
intl: ^0.18.0
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
|
||||
|
|
|
@ -399,5 +399,5 @@ packages:
|
|||
source: hosted
|
||||
version: "0.2.0+3"
|
||||
sdks:
|
||||
dart: ">=2.18.1 <4.0.0"
|
||||
dart: ">=2.18.1 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
#include <list>
|
||||
#include "thread"
|
||||
#include "CwWalletListener.h"
|
||||
#if __APPLE__
|
||||
|
@ -182,6 +183,62 @@ extern "C"
|
|||
}
|
||||
};
|
||||
|
||||
struct CoinsInfoRow
|
||||
{
|
||||
uint64_t blockHeight;
|
||||
char *hash;
|
||||
uint64_t internalOutputIndex;
|
||||
uint64_t globalOutputIndex;
|
||||
bool spent;
|
||||
bool frozen;
|
||||
uint64_t spentHeight;
|
||||
uint64_t amount;
|
||||
bool rct;
|
||||
bool keyImageKnown;
|
||||
uint64_t pkIndex;
|
||||
uint32_t subaddrIndex;
|
||||
uint32_t subaddrAccount;
|
||||
char *address;
|
||||
char *addressLabel;
|
||||
char *keyImage;
|
||||
uint64_t unlockTime;
|
||||
bool unlocked;
|
||||
char *pubKey;
|
||||
bool coinbase;
|
||||
char *description;
|
||||
|
||||
CoinsInfoRow(Monero::CoinsInfo *coinsInfo)
|
||||
{
|
||||
blockHeight = coinsInfo->blockHeight();
|
||||
std::string *hash_str = new std::string(coinsInfo->hash());
|
||||
hash = strdup(hash_str->c_str());
|
||||
internalOutputIndex = coinsInfo->internalOutputIndex();
|
||||
globalOutputIndex = coinsInfo->globalOutputIndex();
|
||||
spent = coinsInfo->spent();
|
||||
frozen = coinsInfo->frozen();
|
||||
spentHeight = coinsInfo->spentHeight();
|
||||
amount = coinsInfo->amount();
|
||||
rct = coinsInfo->rct();
|
||||
keyImageKnown = coinsInfo->keyImageKnown();
|
||||
pkIndex = coinsInfo->pkIndex();
|
||||
subaddrIndex = coinsInfo->subaddrIndex();
|
||||
subaddrAccount = coinsInfo->subaddrAccount();
|
||||
address = strdup(coinsInfo->address().c_str()) ;
|
||||
addressLabel = strdup(coinsInfo->addressLabel().c_str());
|
||||
keyImage = strdup(coinsInfo->keyImage().c_str());
|
||||
unlockTime = coinsInfo->unlockTime();
|
||||
unlocked = coinsInfo->unlocked();
|
||||
pubKey = strdup(coinsInfo->pubKey().c_str());
|
||||
coinbase = coinsInfo->coinbase();
|
||||
description = strdup(coinsInfo->description().c_str());
|
||||
}
|
||||
|
||||
void setUnlocked(bool unlocked);
|
||||
|
||||
};
|
||||
|
||||
Monero::Coins *m_coins;
|
||||
|
||||
Monero::Wallet *m_wallet;
|
||||
Monero::TransactionHistory *m_transaction_history;
|
||||
MoneroWalletListener *m_listener;
|
||||
|
@ -189,6 +246,7 @@ extern "C"
|
|||
Monero::SubaddressAccount *m_account;
|
||||
uint64_t m_last_known_wallet_height;
|
||||
uint64_t m_cached_syncing_blockchain_height = 0;
|
||||
std::list<Monero::CoinsInfo*> m_coins_info;
|
||||
std::mutex store_lock;
|
||||
bool is_storing = false;
|
||||
|
||||
|
@ -224,6 +282,17 @@ extern "C"
|
|||
{
|
||||
m_subaddress = nullptr;
|
||||
}
|
||||
|
||||
m_coins_info = std::list<Monero::CoinsInfo*>();
|
||||
|
||||
if (wallet != nullptr)
|
||||
{
|
||||
m_coins = wallet->coins();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_coins = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Monero::Wallet *get_current_wallet()
|
||||
|
@ -487,9 +556,18 @@ extern "C"
|
|||
}
|
||||
|
||||
bool transaction_create(char *address, char *payment_id, char *amount,
|
||||
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
uint8_t priority_raw, uint32_t subaddr_account,
|
||||
char **preferred_inputs, uint32_t preferred_inputs_size,
|
||||
Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
{
|
||||
nice(19);
|
||||
|
||||
std::set<std::string> _preferred_inputs;
|
||||
|
||||
for (int i = 0; i < preferred_inputs_size; i++) {
|
||||
_preferred_inputs.insert(std::string(*preferred_inputs));
|
||||
preferred_inputs++;
|
||||
}
|
||||
|
||||
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
|
||||
std::string _payment_id;
|
||||
|
@ -503,11 +581,11 @@ extern "C"
|
|||
if (amount != nullptr)
|
||||
{
|
||||
uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount));
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account);
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account);
|
||||
transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional<uint64_t>(), m_wallet->defaultMixin(), priority, subaddr_account, {}, _preferred_inputs);
|
||||
}
|
||||
|
||||
int status = transaction->status();
|
||||
|
@ -527,7 +605,9 @@ extern "C"
|
|||
}
|
||||
|
||||
bool transaction_create_mult_dest(char **addresses, char *payment_id, char **amounts, uint32_t size,
|
||||
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
uint8_t priority_raw, uint32_t subaddr_account,
|
||||
char **preferred_inputs, uint32_t preferred_inputs_size,
|
||||
Utf8Box &error, PendingTransactionRaw &pendingTransaction)
|
||||
{
|
||||
nice(19);
|
||||
|
||||
|
@ -541,6 +621,13 @@ extern "C"
|
|||
amounts++;
|
||||
}
|
||||
|
||||
std::set<std::string> _preferred_inputs;
|
||||
|
||||
for (int i = 0; i < preferred_inputs_size; i++) {
|
||||
_preferred_inputs.insert(std::string(*preferred_inputs));
|
||||
preferred_inputs++;
|
||||
}
|
||||
|
||||
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
|
||||
std::string _payment_id;
|
||||
Monero::PendingTransaction *transaction;
|
||||
|
@ -800,6 +887,91 @@ extern "C"
|
|||
return m_wallet->trustedDaemon();
|
||||
}
|
||||
|
||||
CoinsInfoRow* coin(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_coins_info.size()) {
|
||||
std::list<Monero::CoinsInfo*>::iterator it = m_coins_info.begin();
|
||||
std::advance(it, index);
|
||||
Monero::CoinsInfo* element = *it;
|
||||
std::cout << "Element at index " << index << ": " << element << std::endl;
|
||||
return new CoinsInfoRow(element);
|
||||
} else {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
return nullptr; // Return a default value (nullptr) for invalid index
|
||||
}
|
||||
}
|
||||
|
||||
void refresh_coins(uint32_t accountIndex)
|
||||
{
|
||||
m_coins_info.clear();
|
||||
|
||||
m_coins->refresh();
|
||||
for (const auto i : m_coins->getAll()) {
|
||||
if (i->subaddrAccount() == accountIndex && !(i->spent())) {
|
||||
m_coins_info.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t coins_count()
|
||||
{
|
||||
return m_coins_info.size();
|
||||
}
|
||||
|
||||
CoinsInfoRow** coins_from_account(uint32_t accountIndex)
|
||||
{
|
||||
std::vector<CoinsInfoRow*> matchingCoins;
|
||||
|
||||
for (int i = 0; i < coins_count(); i++) {
|
||||
CoinsInfoRow* coinInfo = coin(i);
|
||||
if (coinInfo->subaddrAccount == accountIndex) {
|
||||
matchingCoins.push_back(coinInfo);
|
||||
}
|
||||
}
|
||||
|
||||
CoinsInfoRow** result = new CoinsInfoRow*[matchingCoins.size()];
|
||||
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
CoinsInfoRow** coins_from_txid(const char* txid, size_t* count)
|
||||
{
|
||||
std::vector<CoinsInfoRow*> matchingCoins;
|
||||
|
||||
for (int i = 0; i < coins_count(); i++) {
|
||||
CoinsInfoRow* coinInfo = coin(i);
|
||||
if (std::string(coinInfo->hash) == txid) {
|
||||
matchingCoins.push_back(coinInfo);
|
||||
}
|
||||
}
|
||||
|
||||
*count = matchingCoins.size();
|
||||
CoinsInfoRow** result = new CoinsInfoRow*[*count];
|
||||
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
CoinsInfoRow** coins_from_key_image(const char** keyimages, size_t keyimageCount, size_t* count)
|
||||
{
|
||||
std::vector<CoinsInfoRow*> matchingCoins;
|
||||
|
||||
for (int i = 0; i < coins_count(); i++) {
|
||||
CoinsInfoRow* coinsInfoRow = coin(i);
|
||||
for (size_t j = 0; j < keyimageCount; j++) {
|
||||
if (coinsInfoRow->keyImageKnown && std::string(coinsInfoRow->keyImage) == keyimages[j]) {
|
||||
matchingCoins.push_back(coinsInfoRow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*count = matchingCoins.size();
|
||||
CoinsInfoRow** result = new CoinsInfoRow*[*count];
|
||||
std::copy(matchingCoins.begin(), matchingCoins.end(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
23
cw_monero/lib/api/coins_info.dart
Normal file
23
cw_monero/lib/api/coins_info.dart
Normal file
|
@ -0,0 +1,23 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:cw_monero/api/signatures.dart';
|
||||
import 'package:cw_monero/api/structs/coins_info_row.dart';
|
||||
import 'package:cw_monero/api/types.dart';
|
||||
import 'package:cw_monero/api/monero_api.dart';
|
||||
|
||||
final refreshCoinsNative = moneroApi
|
||||
.lookup<NativeFunction<refresh_coins>>('refresh_coins')
|
||||
.asFunction<RefreshCoins>();
|
||||
|
||||
final coinsCountNative = moneroApi
|
||||
.lookup<NativeFunction<coins_count>>('coins_count')
|
||||
.asFunction<CoinsCount>();
|
||||
|
||||
final coinNative = moneroApi
|
||||
.lookup<NativeFunction<coin>>('coin')
|
||||
.asFunction<GetCoin>();
|
||||
|
||||
void refreshCoins(int accountIndex) => refreshCoinsNative(accountIndex);
|
||||
|
||||
int countOfCoins() => coinsCountNative();
|
||||
|
||||
CoinsInfoRow getCoin(int index) => coinNative(index).ref;
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:cw_monero/api/structs/coins_info_row.dart';
|
||||
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
||||
import 'package:cw_monero/api/structs/ut8_box.dart';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
@ -9,8 +10,8 @@ typedef create_wallet = Int8 Function(
|
|||
typedef restore_wallet_from_seed = Int8 Function(
|
||||
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
|
||||
|
||||
typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>,
|
||||
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
|
||||
typedef restore_wallet_from_keys = Int8 Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>,
|
||||
Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int32, Int64, Pointer<Utf8>);
|
||||
|
||||
typedef is_wallet_exist = Int8 Function(Pointer<Utf8>);
|
||||
|
||||
|
@ -63,8 +64,7 @@ typedef subaddrress_refresh = Void Function(Int32);
|
|||
|
||||
typedef subaddress_get_all = Pointer<Int64> Function();
|
||||
|
||||
typedef subaddress_add_new = Void Function(
|
||||
Int32 accountIndex, Pointer<Utf8> label);
|
||||
typedef subaddress_add_new = Void Function(Int32 accountIndex, Pointer<Utf8> label);
|
||||
|
||||
typedef subaddress_set_label = Void Function(
|
||||
Int32 accountIndex, Int32 addressIndex, Pointer<Utf8> label);
|
||||
|
@ -77,8 +77,7 @@ typedef account_get_all = Pointer<Int64> Function();
|
|||
|
||||
typedef account_add_new = Void Function(Pointer<Utf8> label);
|
||||
|
||||
typedef account_set_label = Void Function(
|
||||
Int32 accountIndex, Pointer<Utf8> label);
|
||||
typedef account_set_label = Void Function(Int32 accountIndex, Pointer<Utf8> label);
|
||||
|
||||
typedef transactions_refresh = Void Function();
|
||||
|
||||
|
@ -94,6 +93,8 @@ typedef transaction_create = Int8 Function(
|
|||
Pointer<Utf8> amount,
|
||||
Int8 priorityRaw,
|
||||
Int32 subaddrAccount,
|
||||
Pointer<Pointer<Utf8>> preferredInputs,
|
||||
Int32 preferredInputsSize,
|
||||
Pointer<Utf8Box> error,
|
||||
Pointer<PendingTransactionRaw> pendingTransaction);
|
||||
|
||||
|
@ -104,6 +105,8 @@ typedef transaction_create_mult_dest = Int8 Function(
|
|||
Int32 size,
|
||||
Int8 priorityRaw,
|
||||
Int32 subaddrAccount,
|
||||
Pointer<Pointer<Utf8>> preferredInputs,
|
||||
Int32 preferredInputsSize,
|
||||
Pointer<Utf8Box> error,
|
||||
Pointer<PendingTransactionRaw> pendingTransaction);
|
||||
|
||||
|
@ -123,10 +126,16 @@ typedef on_startup = Void Function();
|
|||
|
||||
typedef rescan_blockchain = Void Function();
|
||||
|
||||
typedef get_subaddress_label = Pointer<Utf8> Function(
|
||||
Int32 accountIndex,
|
||||
Int32 addressIndex);
|
||||
typedef get_subaddress_label = Pointer<Utf8> Function(Int32 accountIndex, Int32 addressIndex);
|
||||
|
||||
typedef set_trusted_daemon = Void Function(Int8 trusted);
|
||||
|
||||
typedef trusted_daemon = Int8 Function();
|
||||
typedef trusted_daemon = Int8 Function();
|
||||
|
||||
typedef refresh_coins = Void Function(Int32 accountIndex);
|
||||
|
||||
typedef coins_count = Int64 Function();
|
||||
|
||||
// typedef coins_from_txid = Pointer<CoinsInfoRow> Function(Pointer<Utf8> txid);
|
||||
|
||||
typedef coin = Pointer<CoinsInfoRow> Function(Int32 index);
|
||||
|
|
73
cw_monero/lib/api/structs/coins_info_row.dart
Normal file
73
cw_monero/lib/api/structs/coins_info_row.dart
Normal file
|
@ -0,0 +1,73 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
class CoinsInfoRow extends Struct {
|
||||
@Int64()
|
||||
external int blockHeight;
|
||||
|
||||
external Pointer<Utf8> hash;
|
||||
|
||||
@Uint64()
|
||||
external int internalOutputIndex;
|
||||
|
||||
@Uint64()
|
||||
external int globalOutputIndex;
|
||||
|
||||
@Int8()
|
||||
external int spent;
|
||||
|
||||
@Int8()
|
||||
external int frozen;
|
||||
|
||||
@Uint64()
|
||||
external int spentHeight;
|
||||
|
||||
@Uint64()
|
||||
external int amount;
|
||||
|
||||
@Int8()
|
||||
external int rct;
|
||||
|
||||
@Int8()
|
||||
external int keyImageKnown;
|
||||
|
||||
@Uint64()
|
||||
external int pkIndex;
|
||||
|
||||
@Uint32()
|
||||
external int subaddrIndex;
|
||||
|
||||
@Uint32()
|
||||
external int subaddrAccount;
|
||||
|
||||
external Pointer<Utf8> address;
|
||||
|
||||
external Pointer<Utf8> addressLabel;
|
||||
|
||||
external Pointer<Utf8> keyImage;
|
||||
|
||||
@Uint64()
|
||||
external int unlockTime;
|
||||
|
||||
@Int8()
|
||||
external int unlocked;
|
||||
|
||||
external Pointer<Utf8> pubKey;
|
||||
|
||||
@Int8()
|
||||
external int coinbase;
|
||||
|
||||
external Pointer<Utf8> description;
|
||||
|
||||
String getHash() => hash.toDartString();
|
||||
|
||||
String getAddress() => address.toDartString();
|
||||
|
||||
String getAddressLabel() => addressLabel.toDartString();
|
||||
|
||||
String getKeyImage() => keyImage.toDartString();
|
||||
|
||||
String getPubKey() => pubKey.toDartString();
|
||||
|
||||
String getDescription() => description.toDartString();
|
||||
}
|
|
@ -35,9 +35,8 @@ final transactionCommitNative = moneroApi
|
|||
.lookup<NativeFunction<transaction_commit>>('transaction_commit')
|
||||
.asFunction<TransactionCommit>();
|
||||
|
||||
final getTxKeyNative = moneroApi
|
||||
.lookup<NativeFunction<get_tx_key>>('get_tx_key')
|
||||
.asFunction<GetTxKey>();
|
||||
final getTxKeyNative =
|
||||
moneroApi.lookup<NativeFunction<get_tx_key>>('get_tx_key').asFunction<GetTxKey>();
|
||||
|
||||
String getTxKey(String txId) {
|
||||
final txIdPointer = txId.toNativeUtf8();
|
||||
|
@ -71,10 +70,21 @@ PendingTransactionDescription createTransactionSync(
|
|||
required String paymentId,
|
||||
required int priorityRaw,
|
||||
String? amount,
|
||||
int accountIndex = 0}) {
|
||||
int accountIndex = 0,
|
||||
List<String> preferredInputs = const []}) {
|
||||
final addressPointer = address.toNativeUtf8();
|
||||
final paymentIdPointer = paymentId.toNativeUtf8();
|
||||
final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr;
|
||||
|
||||
final int preferredInputsSize = preferredInputs.length;
|
||||
final List<Pointer<Utf8>> preferredInputsPointers =
|
||||
preferredInputs.map((output) => output.toNativeUtf8()).toList();
|
||||
final Pointer<Pointer<Utf8>> preferredInputsPointerPointer = calloc(preferredInputsSize);
|
||||
|
||||
for (int i = 0; i < preferredInputsSize; i++) {
|
||||
preferredInputsPointerPointer[i] = preferredInputsPointers[i];
|
||||
}
|
||||
|
||||
final errorMessagePointer = calloc<Utf8Box>();
|
||||
final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
|
||||
final created = transactionCreateNative(
|
||||
|
@ -83,10 +93,16 @@ PendingTransactionDescription createTransactionSync(
|
|||
amountPointer,
|
||||
priorityRaw,
|
||||
accountIndex,
|
||||
preferredInputsPointerPointer,
|
||||
preferredInputsSize,
|
||||
errorMessagePointer,
|
||||
pendingTransactionRawPointer) !=
|
||||
0;
|
||||
|
||||
calloc.free(preferredInputsPointerPointer);
|
||||
|
||||
preferredInputsPointers.forEach((element) => calloc.free(element));
|
||||
|
||||
calloc.free(addressPointer);
|
||||
calloc.free(paymentIdPointer);
|
||||
|
||||
|
@ -111,15 +127,16 @@ PendingTransactionDescription createTransactionSync(
|
|||
|
||||
PendingTransactionDescription createTransactionMultDestSync(
|
||||
{required List<MoneroOutput> outputs,
|
||||
required String paymentId,
|
||||
required int priorityRaw,
|
||||
int accountIndex = 0}) {
|
||||
required String paymentId,
|
||||
required int priorityRaw,
|
||||
int accountIndex = 0,
|
||||
List<String> preferredInputs = const []}) {
|
||||
final int size = outputs.length;
|
||||
final List<Pointer<Utf8>> addressesPointers = outputs.map((output) =>
|
||||
output.address.toNativeUtf8()).toList();
|
||||
final List<Pointer<Utf8>> addressesPointers =
|
||||
outputs.map((output) => output.address.toNativeUtf8()).toList();
|
||||
final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size);
|
||||
final List<Pointer<Utf8>> amountsPointers = outputs.map((output) =>
|
||||
output.amount.toNativeUtf8()).toList();
|
||||
final List<Pointer<Utf8>> amountsPointers =
|
||||
outputs.map((output) => output.amount.toNativeUtf8()).toList();
|
||||
final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc(size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
@ -127,25 +144,38 @@ PendingTransactionDescription createTransactionMultDestSync(
|
|||
amountsPointerPointer[i] = amountsPointers[i];
|
||||
}
|
||||
|
||||
final int preferredInputsSize = preferredInputs.length;
|
||||
final List<Pointer<Utf8>> preferredInputsPointers =
|
||||
preferredInputs.map((output) => output.toNativeUtf8()).toList();
|
||||
final Pointer<Pointer<Utf8>> preferredInputsPointerPointer = calloc(preferredInputsSize);
|
||||
|
||||
for (int i = 0; i < preferredInputsSize; i++) {
|
||||
preferredInputsPointerPointer[i] = preferredInputsPointers[i];
|
||||
}
|
||||
|
||||
final paymentIdPointer = paymentId.toNativeUtf8();
|
||||
final errorMessagePointer = calloc<Utf8Box>();
|
||||
final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
|
||||
final created = transactionCreateMultDestNative(
|
||||
addressesPointerPointer,
|
||||
paymentIdPointer,
|
||||
amountsPointerPointer,
|
||||
size,
|
||||
priorityRaw,
|
||||
accountIndex,
|
||||
errorMessagePointer,
|
||||
pendingTransactionRawPointer) !=
|
||||
addressesPointerPointer,
|
||||
paymentIdPointer,
|
||||
amountsPointerPointer,
|
||||
size,
|
||||
priorityRaw,
|
||||
accountIndex,
|
||||
preferredInputsPointerPointer,
|
||||
preferredInputsSize,
|
||||
errorMessagePointer,
|
||||
pendingTransactionRawPointer) !=
|
||||
0;
|
||||
|
||||
calloc.free(addressesPointerPointer);
|
||||
calloc.free(amountsPointerPointer);
|
||||
calloc.free(preferredInputsPointerPointer);
|
||||
|
||||
addressesPointers.forEach((element) => calloc.free(element));
|
||||
amountsPointers.forEach((element) => calloc.free(element));
|
||||
preferredInputsPointers.forEach((element) => calloc.free(element));
|
||||
|
||||
calloc.free(paymentIdPointer);
|
||||
|
||||
|
@ -164,13 +194,12 @@ PendingTransactionDescription createTransactionMultDestSync(
|
|||
pointerAddress: pendingTransactionRawPointer.address);
|
||||
}
|
||||
|
||||
void commitTransactionFromPointerAddress({required int address}) => commitTransaction(
|
||||
transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
|
||||
void commitTransactionFromPointerAddress({required int address}) =>
|
||||
commitTransaction(transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
|
||||
|
||||
void commitTransaction({required Pointer<PendingTransactionRaw> transactionPointer}) {
|
||||
final errorMessagePointer = calloc<Utf8Box>();
|
||||
final isCommited =
|
||||
transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
|
||||
final isCommited = transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
|
||||
|
||||
if (!isCommited) {
|
||||
final message = errorMessagePointer.ref.getValue();
|
||||
|
@ -185,13 +214,15 @@ PendingTransactionDescription _createTransactionSync(Map args) {
|
|||
final amount = args['amount'] as String?;
|
||||
final priorityRaw = args['priorityRaw'] as int;
|
||||
final accountIndex = args['accountIndex'] as int;
|
||||
final preferredInputs = args['preferredInputs'] as List<String>;
|
||||
|
||||
return createTransactionSync(
|
||||
address: address,
|
||||
paymentId: paymentId,
|
||||
amount: amount,
|
||||
priorityRaw: priorityRaw,
|
||||
accountIndex: accountIndex);
|
||||
accountIndex: accountIndex,
|
||||
preferredInputs: preferredInputs);
|
||||
}
|
||||
|
||||
PendingTransactionDescription _createTransactionMultDestSync(Map args) {
|
||||
|
@ -199,12 +230,14 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) {
|
|||
final paymentId = args['paymentId'] as String;
|
||||
final priorityRaw = args['priorityRaw'] as int;
|
||||
final accountIndex = args['accountIndex'] as int;
|
||||
final preferredInputs = args['preferredInputs'] as List<String>;
|
||||
|
||||
return createTransactionMultDestSync(
|
||||
outputs: outputs,
|
||||
paymentId: paymentId,
|
||||
priorityRaw: priorityRaw,
|
||||
accountIndex: accountIndex);
|
||||
accountIndex: accountIndex,
|
||||
preferredInputs: preferredInputs);
|
||||
}
|
||||
|
||||
Future<PendingTransactionDescription> createTransaction(
|
||||
|
@ -212,23 +245,27 @@ Future<PendingTransactionDescription> createTransaction(
|
|||
required int priorityRaw,
|
||||
String? amount,
|
||||
String paymentId = '',
|
||||
int accountIndex = 0}) =>
|
||||
int accountIndex = 0,
|
||||
List<String> preferredInputs = const []}) =>
|
||||
compute(_createTransactionSync, {
|
||||
'address': address,
|
||||
'paymentId': paymentId,
|
||||
'amount': amount,
|
||||
'priorityRaw': priorityRaw,
|
||||
'accountIndex': accountIndex
|
||||
'accountIndex': accountIndex,
|
||||
'preferredInputs': preferredInputs
|
||||
});
|
||||
|
||||
Future<PendingTransactionDescription> createTransactionMultDest(
|
||||
{required List<MoneroOutput> outputs,
|
||||
required int priorityRaw,
|
||||
String paymentId = '',
|
||||
int accountIndex = 0}) =>
|
||||
{required List<MoneroOutput> outputs,
|
||||
required int priorityRaw,
|
||||
String paymentId = '',
|
||||
int accountIndex = 0,
|
||||
List<String> preferredInputs = const []}) =>
|
||||
compute(_createTransactionMultDestSync, {
|
||||
'outputs': outputs,
|
||||
'paymentId': paymentId,
|
||||
'priorityRaw': priorityRaw,
|
||||
'accountIndex': accountIndex
|
||||
'accountIndex': accountIndex,
|
||||
'preferredInputs': preferredInputs
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:cw_monero/api/structs/coins_info_row.dart';
|
||||
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
||||
import 'package:cw_monero/api/structs/ut8_box.dart';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
@ -92,6 +93,8 @@ typedef TransactionCreate = int Function(
|
|||
Pointer<Utf8> amount,
|
||||
int priorityRaw,
|
||||
int subaddrAccount,
|
||||
Pointer<Pointer<Utf8>> preferredInputs,
|
||||
int preferredInputsSize,
|
||||
Pointer<Utf8Box> error,
|
||||
Pointer<PendingTransactionRaw> pendingTransaction);
|
||||
|
||||
|
@ -102,6 +105,8 @@ typedef TransactionCreateMultDest = int Function(
|
|||
int size,
|
||||
int priorityRaw,
|
||||
int subaddrAccount,
|
||||
Pointer<Pointer<Utf8>> preferredInputs,
|
||||
int preferredInputsSize,
|
||||
Pointer<Utf8Box> error,
|
||||
Pointer<PendingTransactionRaw> pendingTransaction);
|
||||
|
||||
|
@ -127,4 +132,10 @@ typedef GetSubaddressLabel = Pointer<Utf8> Function(
|
|||
|
||||
typedef SetTrustedDaemon = void Function(int);
|
||||
|
||||
typedef TrustedDaemon = int Function();
|
||||
typedef TrustedDaemon = int Function();
|
||||
|
||||
typedef RefreshCoins = void Function(int);
|
||||
|
||||
typedef CoinsCount = int Function();
|
||||
|
||||
typedef GetCoin = Pointer<CoinsInfoRow> Function(int);
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
class MoneroTransactionNoInputsException implements Exception {
|
||||
@override
|
||||
String toString() => 'Not enough inputs available. Please select more under Coin Control';
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:cw_monero/api/structs/subaddress_row.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_monero/api/coins_info.dart';
|
||||
import 'package:cw_monero/api/subaddress_list.dart' as subaddress_list;
|
||||
import 'package:cw_core/subaddress.dart';
|
||||
|
||||
|
@ -22,6 +22,8 @@ abstract class MoneroSubaddressListBase with Store {
|
|||
bool _isUpdating;
|
||||
|
||||
void update({required int accountIndex}) {
|
||||
refreshCoins(accountIndex);
|
||||
|
||||
if (_isUpdating) {
|
||||
return;
|
||||
}
|
||||
|
|
28
cw_monero/lib/monero_unspent.dart
Normal file
28
cw_monero/lib/monero_unspent.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
import 'package:cw_monero/api/structs/coins_info_row.dart';
|
||||
|
||||
class MoneroUnspent {
|
||||
MoneroUnspent(this.address, this.hash, this.keyImage, this.value, this.isFrozen, this.isUnlocked)
|
||||
: isSending = true,
|
||||
note = '';
|
||||
|
||||
MoneroUnspent.fromCoinsInfoRow(CoinsInfoRow coinsInfoRow)
|
||||
: address = coinsInfoRow.getAddress(),
|
||||
hash = coinsInfoRow.getHash(),
|
||||
keyImage = coinsInfoRow.getKeyImage(),
|
||||
value = coinsInfoRow.amount,
|
||||
isFrozen = coinsInfoRow.frozen == 1,
|
||||
isUnlocked = coinsInfoRow.unlocked == 1,
|
||||
isSending = true,
|
||||
note = '';
|
||||
|
||||
final String address;
|
||||
final String hash;
|
||||
final String keyImage;
|
||||
final int value;
|
||||
|
||||
final bool isUnlocked;
|
||||
|
||||
bool isFrozen;
|
||||
bool isSending;
|
||||
String note;
|
||||
}
|
|
@ -1,33 +1,35 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_monero/monero_transaction_creation_exception.dart';
|
||||
import 'package:cw_monero/monero_transaction_info.dart';
|
||||
import 'package:cw_monero/monero_wallet_addresses.dart';
|
||||
import 'package:cw_core/monero_wallet_utils.dart';
|
||||
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_monero/api/transaction_history.dart'
|
||||
as monero_transaction_history;
|
||||
import 'package:cw_monero/api/wallet.dart';
|
||||
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
|
||||
import 'package:cw_monero/api/transaction_history.dart' as transaction_history;
|
||||
import 'package:cw_monero/api/monero_output.dart';
|
||||
import 'package:cw_monero/monero_transaction_creation_credentials.dart';
|
||||
import 'package:cw_monero/pending_monero_transaction.dart';
|
||||
import 'package:cw_core/monero_wallet_keys.dart';
|
||||
import 'package:cw_core/monero_balance.dart';
|
||||
import 'package:cw_monero/monero_transaction_history.dart';
|
||||
import 'package:cw_core/account.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/monero_transaction_priority.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_core/monero_balance.dart';
|
||||
import 'package:cw_core/monero_transaction_priority.dart';
|
||||
import 'package:cw_core/monero_wallet_keys.dart';
|
||||
import 'package:cw_core/monero_wallet_utils.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_monero/api/coins_info.dart';
|
||||
import 'package:cw_monero/api/monero_output.dart';
|
||||
import 'package:cw_monero/api/structs/pending_transaction.dart';
|
||||
import 'package:cw_monero/api/transaction_history.dart' as transaction_history;
|
||||
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
|
||||
import 'package:cw_monero/exceptions/monero_transaction_creation_exception.dart';
|
||||
import 'package:cw_monero/exceptions/monero_transaction_no_inputs_exception.dart';
|
||||
import 'package:cw_monero/pending_monero_transaction.dart';
|
||||
import 'package:cw_monero/monero_transaction_creation_credentials.dart';
|
||||
import 'package:cw_monero/monero_transaction_history.dart';
|
||||
import 'package:cw_monero/monero_transaction_info.dart';
|
||||
import 'package:cw_monero/monero_unspent.dart';
|
||||
import 'package:cw_monero/monero_wallet_addresses.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'monero_wallet.g.dart';
|
||||
|
||||
|
@ -37,37 +39,39 @@ class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
|
|||
|
||||
abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
||||
MoneroTransactionHistory, MoneroTransactionInfo> with Store {
|
||||
MoneroWalletBase({required WalletInfo walletInfo})
|
||||
MoneroWalletBase({required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo})
|
||||
: balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({
|
||||
CryptoCurrency.xmr: MoneroBalance(
|
||||
CryptoCurrency.xmr: MoneroBalance(
|
||||
fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
|
||||
unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0))
|
||||
}),
|
||||
}),
|
||||
_isTransactionUpdating = false,
|
||||
_hasSyncAfterStartup = false,
|
||||
walletAddresses = MoneroWalletAddresses(walletInfo),
|
||||
syncStatus = NotConnectedSyncStatus(),
|
||||
unspentCoins = [],
|
||||
this.unspentCoinsInfo = unspentCoinsInfo,
|
||||
super(walletInfo) {
|
||||
transactionHistory = MoneroTransactionHistory();
|
||||
_onAccountChangeReaction = reaction((_) => walletAddresses.account,
|
||||
(Account? account) {
|
||||
_onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) {
|
||||
if (account == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(
|
||||
<CryptoCurrency, MoneroBalance>{
|
||||
currency: MoneroBalance(
|
||||
balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{
|
||||
currency: MoneroBalance(
|
||||
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
|
||||
unlockedBalance:
|
||||
monero_wallet.getUnlockedBalance(accountIndex: account.id))
|
||||
});
|
||||
unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: account.id))
|
||||
});
|
||||
walletAddresses.updateSubaddressList(accountIndex: account.id);
|
||||
});
|
||||
}
|
||||
|
||||
static const int _autoSaveInterval = 30;
|
||||
|
||||
Box<UnspentCoinsInfo> unspentCoinsInfo;
|
||||
|
||||
@override
|
||||
MoneroWalletAddresses walletAddresses;
|
||||
|
||||
|
@ -89,11 +93,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
publicSpendKey: monero_wallet.getPublicSpendKey(),
|
||||
publicViewKey: monero_wallet.getPublicViewKey());
|
||||
|
||||
SyncListener? _listener;
|
||||
monero_wallet.SyncListener? _listener;
|
||||
ReactionDisposer? _onAccountChangeReaction;
|
||||
bool _isTransactionUpdating;
|
||||
bool _hasSyncAfterStartup;
|
||||
Timer? _autoSaveTimer;
|
||||
List<MoneroUnspent> unspentCoins;
|
||||
|
||||
Future<void> init() async {
|
||||
await walletAddresses.init();
|
||||
|
@ -170,10 +175,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
@override
|
||||
Future<PendingTransaction> createTransaction(Object credentials) async {
|
||||
final _credentials = credentials as MoneroTransactionCreationCredentials;
|
||||
final inputs = <String>[];
|
||||
final outputs = _credentials.outputs;
|
||||
final hasMultiDestination = outputs.length > 1;
|
||||
final unlockedBalance =
|
||||
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
|
||||
var allInputsAmount = 0;
|
||||
|
||||
PendingTransactionDescription pendingTransactionDescription;
|
||||
|
||||
|
@ -181,6 +188,21 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
throw MoneroTransactionCreationException('The wallet is not synced.');
|
||||
}
|
||||
|
||||
if (unspentCoins.isEmpty) {
|
||||
await updateUnspent();
|
||||
}
|
||||
|
||||
for (final utx in unspentCoins) {
|
||||
if (utx.isSending) {
|
||||
allInputsAmount += utx.value;
|
||||
inputs.add(utx.keyImage);
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs.isEmpty) {
|
||||
throw MoneroTransactionNoInputsException();
|
||||
}
|
||||
|
||||
if (hasMultiDestination) {
|
||||
if (outputs.any((item) => item.sendAll
|
||||
|| (item.formattedCryptoAmount ?? 0) <= 0)) {
|
||||
|
@ -208,7 +230,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
await transaction_history.createTransactionMultDest(
|
||||
outputs: moneroOutputs,
|
||||
priorityRaw: _credentials.priority.serialize(),
|
||||
accountIndex: walletAddresses.account!.id);
|
||||
accountIndex: walletAddresses.account!.id,
|
||||
preferredInputs: inputs);
|
||||
} else {
|
||||
final output = outputs.first;
|
||||
final address = output.isParsedAddress
|
||||
|
@ -229,12 +252,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
|
||||
}
|
||||
|
||||
pendingTransactionDescription =
|
||||
await transaction_history.createTransaction(
|
||||
pendingTransactionDescription = await transaction_history.createTransaction(
|
||||
address: address!,
|
||||
amount: amount,
|
||||
priorityRaw: _credentials.priority.serialize(),
|
||||
accountIndex: walletAddresses.account!.id);
|
||||
accountIndex: walletAddresses.account!.id,
|
||||
preferredInputs: inputs);
|
||||
}
|
||||
|
||||
return PendingMoneroTransaction(pendingTransactionDescription);
|
||||
|
@ -354,6 +377,85 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
await walletInfo.save();
|
||||
}
|
||||
|
||||
Future<void> updateUnspent() async {
|
||||
refreshCoins(walletAddresses.account!.id);
|
||||
|
||||
unspentCoins.clear();
|
||||
|
||||
final coinCount = countOfCoins();
|
||||
for (var i = 0; i < coinCount; i++) {
|
||||
final coin = getCoin(i);
|
||||
if (coin.spent == 0) {
|
||||
unspentCoins.add(MoneroUnspent.fromCoinsInfoRow(coin));
|
||||
}
|
||||
}
|
||||
|
||||
if (unspentCoinsInfo.isEmpty) {
|
||||
unspentCoins.forEach((coin) => _addCoinInfo(coin));
|
||||
return;
|
||||
}
|
||||
|
||||
if (unspentCoins.isNotEmpty) {
|
||||
unspentCoins.forEach((coin) {
|
||||
final coinInfoList = unspentCoinsInfo.values.where((element) =>
|
||||
element.walletId.contains(id) && element.hash.contains(coin.hash));
|
||||
|
||||
if (coinInfoList.isNotEmpty) {
|
||||
final coinInfo = coinInfoList.first;
|
||||
|
||||
coin.isFrozen = coinInfo.isFrozen;
|
||||
coin.isSending = coinInfo.isSending;
|
||||
coin.note = coinInfo.note;
|
||||
} else {
|
||||
_addCoinInfo(coin);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await _refreshUnspentCoinsInfo();
|
||||
_askForUpdateBalance();
|
||||
}
|
||||
|
||||
Future<void> _addCoinInfo(MoneroUnspent coin) async {
|
||||
final newInfo = UnspentCoinsInfo(
|
||||
walletId: id,
|
||||
hash: coin.hash,
|
||||
isFrozen: coin.isFrozen,
|
||||
isSending: coin.isSending,
|
||||
noteRaw: coin.note,
|
||||
address: coin.address,
|
||||
value: coin.value,
|
||||
vout: 0,
|
||||
keyImage: coin.keyImage
|
||||
);
|
||||
|
||||
await unspentCoinsInfo.add(newInfo);
|
||||
}
|
||||
|
||||
Future<void> _refreshUnspentCoinsInfo() async {
|
||||
try {
|
||||
final List<dynamic> keys = <dynamic>[];
|
||||
final currentWalletUnspentCoins = unspentCoinsInfo.values
|
||||
.where((element) => element.walletId.contains(id));
|
||||
|
||||
if (currentWalletUnspentCoins.isNotEmpty) {
|
||||
currentWalletUnspentCoins.forEach((element) {
|
||||
final existUnspentCoins = unspentCoins.where((coin) => element.hash.contains(coin.hash));
|
||||
|
||||
if (existUnspentCoins.isEmpty) {
|
||||
keys.add(element.key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (keys.isNotEmpty) {
|
||||
await unspentCoinsInfo.deleteAll(keys);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
String getTransactionAddress(int accountIndex, int addressIndex) =>
|
||||
monero_wallet.getAddress(
|
||||
accountIndex: accountIndex,
|
||||
|
@ -361,7 +463,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
|
||||
@override
|
||||
Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async {
|
||||
monero_transaction_history.refreshTransactions();
|
||||
transaction_history.refreshTransactions();
|
||||
return _getAllTransactions(null).fold<Map<String, MoneroTransactionInfo>>(
|
||||
<String, MoneroTransactionInfo>{},
|
||||
(Map<String, MoneroTransactionInfo> acc, MoneroTransactionInfo tx) {
|
||||
|
@ -392,7 +494,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
}
|
||||
|
||||
List<MoneroTransactionInfo> _getAllTransactions(dynamic _) =>
|
||||
monero_transaction_history
|
||||
transaction_history
|
||||
.getAllTransations()
|
||||
.map((row) => MoneroTransactionInfo.fromRow(row))
|
||||
.toList();
|
||||
|
@ -407,7 +509,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
return;
|
||||
}
|
||||
|
||||
final currentHeight = getCurrentHeight();
|
||||
final currentHeight = monero_wallet.getCurrentHeight();
|
||||
|
||||
if (currentHeight <= 1) {
|
||||
final height = _getHeightByDate(walletInfo.date);
|
||||
|
@ -439,11 +541,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
void _askForUpdateBalance() {
|
||||
final unlockedBalance = _getUnlockedBalance();
|
||||
final fullBalance = _getFullBalance();
|
||||
final frozenBalance = _getFrozenBalance();
|
||||
|
||||
if (balance[currency]!.fullBalance != fullBalance ||
|
||||
balance[currency]!.unlockedBalance != unlockedBalance) {
|
||||
balance[currency]!.unlockedBalance != unlockedBalance ||
|
||||
balance[currency]!.frozenBalance != frozenBalance) {
|
||||
balance[currency] = MoneroBalance(
|
||||
fullBalance: fullBalance, unlockedBalance: unlockedBalance);
|
||||
fullBalance: fullBalance, unlockedBalance: unlockedBalance, frozenBalance: frozenBalance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -456,6 +560,17 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
int _getUnlockedBalance() =>
|
||||
monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
|
||||
|
||||
int _getFrozenBalance() {
|
||||
var frozenBalance = 0;
|
||||
|
||||
for (var coin in unspentCoinsInfo.values) {
|
||||
if (coin.isFrozen)
|
||||
frozenBalance += coin.value;
|
||||
}
|
||||
|
||||
return frozenBalance;
|
||||
}
|
||||
|
||||
void _onNewBlock(int height, int blocksLeft, double ptc) async {
|
||||
try {
|
||||
if (walletInfo.isRecovery) {
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import 'dart:io';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/monero_wallet_utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
|
||||
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
|
||||
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_service.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_service.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
|
||||
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
class MoneroNewWalletCredentials extends WalletCredentials {
|
||||
MoneroNewWalletCredentials({required String name, required this.language, String? password})
|
||||
|
@ -53,9 +53,10 @@ class MoneroWalletService extends WalletService<
|
|||
MoneroNewWalletCredentials,
|
||||
MoneroRestoreWalletFromSeedCredentials,
|
||||
MoneroRestoreWalletFromKeysCredentials> {
|
||||
MoneroWalletService(this.walletInfoSource);
|
||||
MoneroWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
||||
|
||||
static bool walletFilesExist(String path) =>
|
||||
!File(path).existsSync() && !File('$path.keys').existsSync();
|
||||
|
@ -71,7 +72,8 @@ class MoneroWalletService extends WalletService<
|
|||
path: path,
|
||||
password: credentials.password!,
|
||||
language: credentials.language);
|
||||
final wallet = MoneroWallet(walletInfo: credentials.walletInfo!);
|
||||
final wallet = MoneroWallet(
|
||||
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
@ -107,7 +109,7 @@ class MoneroWalletService extends WalletService<
|
|||
.openWalletAsync({'path': path, 'password': password});
|
||||
final walletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()));
|
||||
final wallet = MoneroWallet(walletInfo: walletInfo);
|
||||
final wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
final isValid = wallet.walletAddresses.validate();
|
||||
|
||||
if (!isValid) {
|
||||
|
@ -157,7 +159,8 @@ class MoneroWalletService extends WalletService<
|
|||
String currentName, String password, String newName) async {
|
||||
final currentWalletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(currentName, getType()));
|
||||
final currentWallet = MoneroWallet(walletInfo: currentWalletInfo);
|
||||
final currentWallet =
|
||||
MoneroWallet(walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
|
||||
await currentWallet.renameWalletFiles(newName);
|
||||
|
||||
|
@ -181,7 +184,8 @@ class MoneroWalletService extends WalletService<
|
|||
address: credentials.address,
|
||||
viewKey: credentials.viewKey,
|
||||
spendKey: credentials.spendKey);
|
||||
final wallet = MoneroWallet(walletInfo: credentials.walletInfo!);
|
||||
final wallet = MoneroWallet(
|
||||
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
@ -202,7 +206,8 @@ class MoneroWalletService extends WalletService<
|
|||
password: credentials.password!,
|
||||
seed: credentials.mnemonic,
|
||||
restoreHeight: credentials.height!);
|
||||
final wallet = MoneroWallet(walletInfo: credentials.walletInfo!);
|
||||
final wallet = MoneroWallet(
|
||||
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.init();
|
||||
|
||||
return wallet;
|
||||
|
|
|
@ -672,5 +672,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.19.0 <4.0.0"
|
||||
dart: ">=2.19.0 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -13,11 +13,11 @@ dependencies:
|
|||
flutter:
|
||||
sdk: flutter
|
||||
ffi: ^2.0.1
|
||||
http: ^0.13.4
|
||||
http: ^1.1.0
|
||||
path_provider: ^2.0.11
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
intl: ^0.18.0
|
||||
encrypt: ^5.0.1
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
|
|
|
@ -5,7 +5,7 @@ author: Cake Walelt
|
|||
homepage: https://cakewallet.com
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
The following are the system requirements to build CakeWallet for your Android device.
|
||||
|
||||
```
|
||||
Ubuntu >= 16.04
|
||||
Ubuntu >= 20.04
|
||||
Android SDK 29 or higher (better to have the latest one 33)
|
||||
Android NDK 17c
|
||||
Flutter 3.7.x
|
||||
Flutter 3.10.x or earlier
|
||||
```
|
||||
|
||||
## Building CakeWallet on Android
|
||||
|
@ -66,7 +66,7 @@ Verify that the Android toolchain, Flutter, and Android Studio have been correct
|
|||
The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding.
|
||||
```
|
||||
Doctor summary (to see all details, run flutter doctor -v):
|
||||
[✓] Flutter (Channel stable, 3.7.x, on Linux, locale en_US.UTF-8)
|
||||
[✓] Flutter (Channel stable, 3.10.x, on Linux, locale en_US.UTF-8)
|
||||
[✓] Android toolchain - develop for Android devices (Android SDK version 29 or higher)
|
||||
[✓] Android Studio (version 4.0 or higher)
|
||||
```
|
||||
|
|
|
@ -174,12 +174,12 @@ DEPENDENCIES:
|
|||
- 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`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
|
||||
- sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`)
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- uni_links (from `.symlinks/plugins/uni_links/ios`)
|
||||
- UnstoppableDomainsResolution (~> 4.0.0)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
|
@ -236,7 +236,7 @@ EXTERNAL SOURCES:
|
|||
package_info:
|
||||
:path: ".symlinks/plugins/package_info/ios"
|
||||
path_provider_foundation:
|
||||
:path: ".symlinks/plugins/path_provider_foundation/ios"
|
||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||
permission_handler_apple:
|
||||
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||
platform_device_id:
|
||||
|
@ -246,7 +246,7 @@ EXTERNAL SOURCES:
|
|||
share_plus:
|
||||
:path: ".symlinks/plugins/share_plus/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
uni_links:
|
||||
:path: ".symlinks/plugins/uni_links/ios"
|
||||
url_launcher_ios:
|
||||
|
|
|
@ -182,6 +182,8 @@ class AnonPayApi {
|
|||
switch (currency) {
|
||||
case CryptoCurrency.usdt:
|
||||
return CryptoCurrency.btc.title.toLowerCase();
|
||||
case CryptoCurrency.eth:
|
||||
return 'ERC20';
|
||||
default:
|
||||
return currency.tag != null ? _normalizeTag(currency.tag!) : 'Mainnet';
|
||||
}
|
||||
|
|
|
@ -137,7 +137,8 @@ class CWBitcoin extends Bitcoin {
|
|||
bitcoinUnspent.address,
|
||||
bitcoinUnspent.hash,
|
||||
bitcoinUnspent.value,
|
||||
bitcoinUnspent.vout))
|
||||
bitcoinUnspent.vout,
|
||||
null))
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
@ -169,4 +170,4 @@ class CWBitcoin extends Bitcoin {
|
|||
@override
|
||||
TransactionPriority getLitecoinTransactionPrioritySlow()
|
||||
=> LitecoinTransactionPriority.slow;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OnRamperBuyProvider {
|
||||
OnRamperBuyProvider({required SettingsStore settingsStore, required WalletBase wallet})
|
||||
|
@ -27,7 +29,11 @@ class OnRamperBuyProvider {
|
|||
}
|
||||
}
|
||||
|
||||
Uri requestUrl() {
|
||||
String getColorStr(Color color) {
|
||||
return color.value.toRadixString(16).replaceAll(RegExp(r'^ff'), "");
|
||||
}
|
||||
|
||||
Uri requestUrl(BuildContext context) {
|
||||
String primaryColor,
|
||||
secondaryColor,
|
||||
primaryTextColor,
|
||||
|
@ -35,31 +41,16 @@ class OnRamperBuyProvider {
|
|||
containerColor,
|
||||
cardColor;
|
||||
|
||||
switch (_settingsStore.currentTheme.type) {
|
||||
case ThemeType.bright:
|
||||
primaryColor = '815dfbff';
|
||||
secondaryColor = 'ffffff';
|
||||
primaryTextColor = '141519';
|
||||
secondaryTextColor = '6b6f80';
|
||||
containerColor = 'ffffff';
|
||||
cardColor = 'f2f0faff';
|
||||
break;
|
||||
case ThemeType.light:
|
||||
primaryColor = '2194ffff';
|
||||
secondaryColor = 'ffffff';
|
||||
primaryTextColor = '141519';
|
||||
secondaryTextColor = '6b6f80';
|
||||
containerColor = 'ffffff';
|
||||
cardColor = 'e5f7ff';
|
||||
break;
|
||||
case ThemeType.dark:
|
||||
primaryColor = '456effff';
|
||||
secondaryColor = '1b2747ff';
|
||||
primaryTextColor = 'ffffff';
|
||||
secondaryTextColor = 'ffffff';
|
||||
containerColor = '19233C';
|
||||
cardColor = '232f4fff';
|
||||
break;
|
||||
primaryColor = getColorStr(Theme.of(context).primaryColor);
|
||||
secondaryColor = getColorStr(Theme.of(context).colorScheme.background);
|
||||
primaryTextColor = getColorStr(Theme.of(context).extension<CakeTextTheme>()!.titleColor);
|
||||
secondaryTextColor =
|
||||
getColorStr(Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor);
|
||||
containerColor = getColorStr(Theme.of(context).colorScheme.background);
|
||||
cardColor = getColorStr(Theme.of(context).cardColor);
|
||||
|
||||
if (_settingsStore.currentTheme.title == S.current.high_contrast_theme) {
|
||||
cardColor = getColorStr(Colors.white);
|
||||
}
|
||||
|
||||
final networkName = _wallet.currency.fullName?.toUpperCase().replaceAll(" ", "");
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:uuid/uuid.dart';
|
||||
import 'package:cw_core/key.dart';
|
||||
|
||||
String generateWalletPassword() {
|
||||
|
|
33
lib/di.dart
33
lib/di.dart
|
@ -178,8 +178,6 @@ import 'package:hive/hive.dart';
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.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/core/wallet_creation_service.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
@ -219,10 +217,10 @@ late Box<Template> _templates;
|
|||
late Box<ExchangeTemplate> _exchangeTemplates;
|
||||
late Box<TransactionDescription> _transactionDescriptionBox;
|
||||
late Box<Order> _ordersSource;
|
||||
late Box<UnspentCoinsInfo>? _unspentCoinsInfoSource;
|
||||
late Box<UnspentCoinsInfo> _unspentCoinsInfoSource;
|
||||
late Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
|
||||
|
||||
Future setup({
|
||||
Future<void> setup({
|
||||
required Box<WalletInfo> walletInfoSource,
|
||||
required Box<Node> nodeSource,
|
||||
required Box<Contact> contactSource,
|
||||
|
@ -231,7 +229,7 @@ Future setup({
|
|||
required Box<ExchangeTemplate> exchangeTemplates,
|
||||
required Box<TransactionDescription> transactionDescriptionBox,
|
||||
required Box<Order> ordersSource,
|
||||
Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
||||
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
|
||||
}) async {
|
||||
_walletInfoSource = walletInfoSource;
|
||||
|
@ -321,25 +319,6 @@ Future setup({
|
|||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
|
||||
type: type));
|
||||
|
||||
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,
|
||||
type: type, language: language, seed: mnemonic);
|
||||
});
|
||||
|
||||
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,
|
||||
type: type, language: language);
|
||||
});
|
||||
|
||||
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
|
||||
return WalletRestorationFromQRVM(getIt.get<AppStore>(),
|
||||
getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
|
||||
|
@ -753,11 +732,11 @@ Future setup({
|
|||
case WalletType.haven:
|
||||
return haven!.createHavenWalletService(_walletInfoSource);
|
||||
case WalletType.monero:
|
||||
return monero!.createMoneroWalletService(_walletInfoSource);
|
||||
return monero!.createMoneroWalletService(_walletInfoSource, _unspentCoinsInfoSource);
|
||||
case WalletType.bitcoin:
|
||||
return bitcoin!.createBitcoinWalletService(_walletInfoSource, _unspentCoinsInfoSource!);
|
||||
return bitcoin!.createBitcoinWalletService(_walletInfoSource, _unspentCoinsInfoSource);
|
||||
case WalletType.litecoin:
|
||||
return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource!);
|
||||
return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumWalletService(_walletInfoSource);
|
||||
case WalletType.bitcoinCash:
|
||||
|
|
|
@ -50,7 +50,7 @@ class MainActions {
|
|||
case WalletType.monero:
|
||||
case WalletType.bitcoinCash:
|
||||
if (viewModel.isEnabledBuyAction) {
|
||||
final uri = getIt.get<OnRamperBuyProvider>().requestUrl();
|
||||
final uri = getIt.get<OnRamperBuyProvider>().requestUrl(context);
|
||||
if (DeviceInfo.instance.isMobile) {
|
||||
Navigator.of(context)
|
||||
.pushNamed(Routes.webViewPage, arguments: [S.of(context).buy, uri]);
|
||||
|
|
18
lib/entities/unspent_transaction_output.dart
Normal file
18
lib/entities/unspent_transaction_output.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
class Unspent {
|
||||
Unspent(this.address, this.hash, this.value, this.vout, this.keyImage)
|
||||
: isSending = true,
|
||||
isFrozen = false,
|
||||
note = '';
|
||||
|
||||
final String address;
|
||||
final String hash;
|
||||
final int value;
|
||||
final int vout;
|
||||
final String? keyImage;
|
||||
|
||||
bool isSending;
|
||||
bool isFrozen;
|
||||
String note;
|
||||
|
||||
bool get isP2wpkh => address.startsWith('bc') || address.startsWith('ltc');
|
||||
}
|
|
@ -22,6 +22,14 @@ class CWEthereum extends Ethereum {
|
|||
}) =>
|
||||
EthereumRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
|
||||
|
||||
@override
|
||||
WalletCredentials createEthereumRestoreWalletFromPrivateKey({
|
||||
required String name,
|
||||
required String privateKey,
|
||||
required String password,
|
||||
}) =>
|
||||
EthereumRestoreWalletFromPrivateKey(name: name, password: password, privateKey: privateKey);
|
||||
|
||||
@override
|
||||
String getAddress(WalletBase wallet) => (wallet as EthereumWallet).walletAddresses.address;
|
||||
|
||||
|
|
|
@ -68,14 +68,12 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
required CryptoCurrency to,
|
||||
required bool isFixedRateMode}) async {
|
||||
final headers = {apiHeaderKey: apiKey};
|
||||
final normalizedFrom = normalizeCryptoCurrency(from);
|
||||
final normalizedTo = normalizeCryptoCurrency(to);
|
||||
final flow = getFlow(isFixedRateMode);
|
||||
final params = <String, String>{
|
||||
'fromCurrency': normalizedFrom,
|
||||
'toCurrency': normalizedTo,
|
||||
'fromNetwork': networkFor(from),
|
||||
'toNetwork': networkFor(to),
|
||||
'fromCurrency': _normalizeCurrency(from),
|
||||
'toCurrency': _normalizeCurrency(to),
|
||||
'fromNetwork': _networkFor(from),
|
||||
'toNetwork': _networkFor(to),
|
||||
'flow': flow
|
||||
};
|
||||
final uri = Uri.https(apiAuthority, rangePath, params);
|
||||
|
@ -112,10 +110,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
final flow = getFlow(isFixedRateMode);
|
||||
final type = isFixedRateMode ? 'reverse' : 'direct';
|
||||
final body = <String, dynamic>{
|
||||
'fromCurrency': normalizeCryptoCurrency(_request.from),
|
||||
'toCurrency': normalizeCryptoCurrency(_request.to),
|
||||
'fromNetwork': networkFor(_request.from),
|
||||
'toNetwork': networkFor(_request.to),
|
||||
'fromCurrency': _normalizeCurrency(_request.from),
|
||||
'toCurrency': _normalizeCurrency(_request.to),
|
||||
'fromNetwork': _networkFor(_request.from),
|
||||
'toNetwork': _networkFor(_request.to),
|
||||
if (!isFixedRateMode) 'fromAmount': _request.fromAmount,
|
||||
if (isFixedRateMode) 'toAmount': _request.toAmount,
|
||||
'address': _request.address,
|
||||
|
@ -241,10 +239,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
final type = isReverse ? 'reverse' : 'direct';
|
||||
final flow = getFlow(isFixedRateMode);
|
||||
final params = <String, String>{
|
||||
'fromCurrency': normalizeCryptoCurrency(from),
|
||||
'toCurrency': normalizeCryptoCurrency(to),
|
||||
'fromNetwork': networkFor(from),
|
||||
'toNetwork': networkFor(to),
|
||||
'fromCurrency': _normalizeCurrency(from),
|
||||
'toCurrency': _normalizeCurrency(to),
|
||||
'fromNetwork': _networkFor(from),
|
||||
'toNetwork': _networkFor(to),
|
||||
'type': type,
|
||||
'flow': flow
|
||||
};
|
||||
|
@ -273,25 +271,34 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
|||
}
|
||||
}
|
||||
|
||||
String networkFor(CryptoCurrency currency) {
|
||||
String _networkFor(CryptoCurrency currency) {
|
||||
switch (currency) {
|
||||
case CryptoCurrency.usdt:
|
||||
return CryptoCurrency.btc.title.toLowerCase();
|
||||
return 'btc';
|
||||
default:
|
||||
return currency.tag != null ? currency.tag!.toLowerCase() : currency.title.toLowerCase();
|
||||
return currency.tag != null ? _normalizeTag(currency.tag!) : currency.title.toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String normalizeCryptoCurrency(CryptoCurrency currency) {
|
||||
switch (currency) {
|
||||
case CryptoCurrency.zec:
|
||||
return 'zec';
|
||||
case CryptoCurrency.usdcpoly:
|
||||
return 'usdcmatic';
|
||||
case CryptoCurrency.maticpoly:
|
||||
return 'maticmainnet';
|
||||
default:
|
||||
return currency.title.toLowerCase();
|
||||
String _normalizeCurrency(CryptoCurrency currency) {
|
||||
switch (currency) {
|
||||
case CryptoCurrency.zec:
|
||||
return 'zec';
|
||||
default:
|
||||
return currency.title.toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String _normalizeTag(String tag) {
|
||||
switch (tag) {
|
||||
case 'POLY':
|
||||
return 'matic';
|
||||
case 'LN':
|
||||
return 'lightning';
|
||||
case 'AVAXC':
|
||||
return 'cchain';
|
||||
default:
|
||||
return tag.toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,7 +28,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
|
|||
CryptoCurrency.xhv,
|
||||
CryptoCurrency.dcr,
|
||||
CryptoCurrency.kmd,
|
||||
CryptoCurrency.mkr,
|
||||
CryptoCurrency.oxt,
|
||||
CryptoCurrency.pivx,
|
||||
CryptoCurrency.rune,
|
||||
|
|
|
@ -20,7 +20,6 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
bool useTorOnly;
|
||||
|
||||
static const List<CryptoCurrency> _notSupported = [
|
||||
CryptoCurrency.scrt,
|
||||
CryptoCurrency.stx,
|
||||
CryptoCurrency.zaddr,
|
||||
];
|
||||
|
@ -60,8 +59,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
}) async {
|
||||
final params = <String, String>{
|
||||
'api_key': apiKey,
|
||||
'ticker_from': request.from.title.toLowerCase(),
|
||||
'ticker_to': request.to.title.toLowerCase(),
|
||||
'ticker_from': _normalizeCurrency(request.from),
|
||||
'ticker_to': _normalizeCurrency(request.to),
|
||||
'network_from': _networkFor(request.from),
|
||||
'network_to': _networkFor(request.to),
|
||||
'payment': isFixedRateMode ? 'True' : 'False',
|
||||
|
@ -137,7 +136,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
required bool isFixedRateMode}) async {
|
||||
final params = <String, String>{
|
||||
'api_key': apiKey,
|
||||
'ticker': from.title.toLowerCase(),
|
||||
'ticker': _normalizeCurrency(from),
|
||||
'name': from.name,
|
||||
};
|
||||
|
||||
|
@ -177,8 +176,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
|
||||
final params = <String, String>{
|
||||
'api_key': apiKey,
|
||||
'ticker_from': from.title.toLowerCase(),
|
||||
'ticker_to': to.title.toLowerCase(),
|
||||
'ticker_from': _normalizeCurrency(from),
|
||||
'ticker_to': _normalizeCurrency(to),
|
||||
'network_from': _networkFor(from),
|
||||
'network_to': _networkFor(to),
|
||||
if (!isFixedRateMode) 'amount_from': amount.toString(),
|
||||
|
@ -279,6 +278,15 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
|||
}
|
||||
}
|
||||
|
||||
String _normalizeCurrency(CryptoCurrency currency) {
|
||||
switch (currency) {
|
||||
case CryptoCurrency.zec:
|
||||
return 'zec';
|
||||
default:
|
||||
return currency.title.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
String _normalizeTag(String tag) {
|
||||
switch (tag) {
|
||||
case 'ETH':
|
||||
|
|
|
@ -736,6 +736,21 @@ class HaMaterialLocalizations extends GlobalMaterialLocalizations {
|
|||
|
||||
@override
|
||||
String get keyboardKeySpace => 'Space';
|
||||
|
||||
@override
|
||||
String get bottomSheetLabel => "Bottom Sheet";
|
||||
|
||||
@override
|
||||
String get currentDateLabel => "Current Date";
|
||||
|
||||
@override
|
||||
String get keyboardKeyShift => "Shift";
|
||||
|
||||
@override
|
||||
String get scrimLabel => "Scrim";
|
||||
|
||||
@override
|
||||
String get scrimOnTapHintRaw => "Scrip on Tap";
|
||||
}
|
||||
|
||||
/// Cupertino Support
|
||||
|
@ -937,4 +952,7 @@ class HaCupertinoLocalizations extends GlobalCupertinoLocalizations {
|
|||
|
||||
static const LocalizationsDelegate<CupertinoLocalizations> delegate =
|
||||
_HaCupertinoLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
String get noSpellCheckReplacementsLabel => "";
|
||||
}
|
||||
|
|
|
@ -736,6 +736,21 @@ String get keyboardKeyMetaWindows => 'Windows';
|
|||
|
||||
@override
|
||||
String get keyboardKeySpace => 'Space';
|
||||
|
||||
@override
|
||||
String get bottomSheetLabel => "Bottom Sheet";
|
||||
|
||||
@override
|
||||
String get currentDateLabel => "Current Date";
|
||||
|
||||
@override
|
||||
String get keyboardKeyShift => "Shift";
|
||||
|
||||
@override
|
||||
String get scrimLabel => "Scrim";
|
||||
|
||||
@override
|
||||
String get scrimOnTapHintRaw => "Scrip on Tap";
|
||||
}
|
||||
|
||||
/// Cupertino Support
|
||||
|
@ -937,4 +952,7 @@ String get todayLabel => 'Oyọ';
|
|||
|
||||
static const LocalizationsDelegate<CupertinoLocalizations> delegate =
|
||||
_YoCupertinoLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
String get noSpellCheckReplacementsLabel => "";
|
||||
}
|
||||
|
|
|
@ -133,11 +133,7 @@ Future<void> initializeAppConfigs() async {
|
|||
final templates = await CakeHive.openBox<Template>(Template.boxName);
|
||||
final exchangeTemplates = await CakeHive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
|
||||
final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
|
||||
Box<UnspentCoinsInfo>? unspentCoinsInfoSource;
|
||||
|
||||
if (!isMoneroOnly) {
|
||||
unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
|
||||
}
|
||||
final unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
|
||||
|
||||
await initialSetup(
|
||||
sharedPreferences: await SharedPreferences.getInstance(),
|
||||
|
@ -169,7 +165,7 @@ Future<void> initialSetup(
|
|||
required Box<TransactionDescription> transactionDescriptions,
|
||||
required FlutterSecureStorage secureStorage,
|
||||
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
|
||||
Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
||||
int initialMigrationVersion = 15}) async {
|
||||
LanguageService.loadLocaleList();
|
||||
await defaultSettingsMigration(
|
||||
|
|
|
@ -1,361 +1,363 @@
|
|||
part of 'monero.dart';
|
||||
|
||||
class CWMoneroAccountList extends MoneroAccountList {
|
||||
CWMoneroAccountList(this._wallet);
|
||||
final Object _wallet;
|
||||
CWMoneroAccountList(this._wallet);
|
||||
|
||||
@override
|
||||
@computed
|
||||
final Object _wallet;
|
||||
|
||||
@override
|
||||
@computed
|
||||
ObservableList<Account> get accounts {
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final accounts = moneroWallet.walletAddresses.accountList
|
||||
.accounts
|
||||
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
|
||||
.toList();
|
||||
return ObservableList<Account>.of(accounts);
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final accounts = moneroWallet.walletAddresses.accountList.accounts
|
||||
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
|
||||
.toList();
|
||||
return ObservableList<Account>.of(accounts);
|
||||
}
|
||||
|
||||
@override
|
||||
void update(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.accountList.update();
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.accountList.update();
|
||||
}
|
||||
|
||||
@override
|
||||
void refresh(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.accountList.refresh();
|
||||
}
|
||||
void refresh(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.accountList.refresh();
|
||||
}
|
||||
|
||||
@override
|
||||
@override
|
||||
List<Account> getAll(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.walletAddresses.accountList
|
||||
.getAll()
|
||||
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
|
||||
.toList();
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.walletAddresses.accountList
|
||||
.getAll()
|
||||
.map((acc) => Account(id: acc.id, label: acc.label, balance: acc.balance))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addAccount(Object wallet, {required String label}) async {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.accountList.addAccount(label: label);
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.accountList.addAccount(label: label);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.accountList
|
||||
.setLabelAccount(
|
||||
accountIndex: accountIndex,
|
||||
label: label);
|
||||
Future<void> setLabelAccount(Object wallet,
|
||||
{required int accountIndex, required String label}) async {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.accountList
|
||||
.setLabelAccount(accountIndex: accountIndex, label: label);
|
||||
}
|
||||
}
|
||||
|
||||
class CWMoneroSubaddressList extends MoneroSubaddressList {
|
||||
CWMoneroSubaddressList(this._wallet);
|
||||
final Object _wallet;
|
||||
CWMoneroSubaddressList(this._wallet);
|
||||
|
||||
@override
|
||||
@computed
|
||||
final Object _wallet;
|
||||
|
||||
@override
|
||||
@computed
|
||||
ObservableList<Subaddress> get subaddresses {
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final subAddresses = moneroWallet.walletAddresses.subaddressList
|
||||
.subaddresses
|
||||
.map((sub) => Subaddress(
|
||||
id: sub.id,
|
||||
address: sub.address,
|
||||
label: sub.label))
|
||||
.toList();
|
||||
return ObservableList<Subaddress>.of(subAddresses);
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final subAddresses = moneroWallet.walletAddresses.subaddressList.subaddresses
|
||||
.map((sub) => Subaddress(id: sub.id, address: sub.address, label: sub.label))
|
||||
.toList();
|
||||
return ObservableList<Subaddress>.of(subAddresses);
|
||||
}
|
||||
|
||||
@override
|
||||
void update(Object wallet, {required int accountIndex}) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
void refresh(Object wallet, {required int accountIndex}) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Subaddress> getAll(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.walletAddresses
|
||||
.subaddressList
|
||||
.getAll()
|
||||
.map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
|
||||
.toList();
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.walletAddresses.subaddressList
|
||||
.getAll()
|
||||
.map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.subaddressList
|
||||
.addSubaddress(
|
||||
accountIndex: accountIndex,
|
||||
label: label);
|
||||
Future<void> addSubaddress(Object wallet,
|
||||
{required int accountIndex, required String label}) async {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.subaddressList
|
||||
.addSubaddress(accountIndex: accountIndex, label: label);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setLabelSubaddress(Object wallet,
|
||||
{required int accountIndex, required int addressIndex, required String label}) async {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.subaddressList
|
||||
.setLabelSubaddress(
|
||||
accountIndex: accountIndex,
|
||||
addressIndex: addressIndex,
|
||||
label: label);
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.walletAddresses.subaddressList
|
||||
.setLabelSubaddress(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
|
||||
}
|
||||
}
|
||||
|
||||
class CWMoneroWalletDetails extends MoneroWalletDetails {
|
||||
CWMoneroWalletDetails(this._wallet);
|
||||
final Object _wallet;
|
||||
CWMoneroWalletDetails(this._wallet);
|
||||
|
||||
@computed
|
||||
final Object _wallet;
|
||||
|
||||
@computed
|
||||
@override
|
||||
Account get account {
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final acc = moneroWallet.walletAddresses.account;
|
||||
return Account(id: acc!.id, label: acc.label, balance: acc.balance);
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final acc = moneroWallet.walletAddresses.account;
|
||||
return Account(id: acc!.id, label: acc.label, balance: acc.balance);
|
||||
}
|
||||
|
||||
@computed
|
||||
@override
|
||||
MoneroBalance get balance {
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final balance = moneroWallet.balance;
|
||||
MoneroBalance get balance {
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final balance = moneroWallet.balance;
|
||||
throw Exception('Unimplemented');
|
||||
// return MoneroBalance();
|
||||
//return MoneroBalance(
|
||||
// fullBalance: balance.fullBalance,
|
||||
// unlockedBalance: balance.unlockedBalance);
|
||||
}
|
||||
// return MoneroBalance();
|
||||
//return MoneroBalance(
|
||||
// fullBalance: balance.fullBalance,
|
||||
// unlockedBalance: balance.unlockedBalance);
|
||||
}
|
||||
}
|
||||
|
||||
class CWMonero extends Monero {
|
||||
@override
|
||||
MoneroAccountList getAccountList(Object wallet) {
|
||||
return CWMoneroAccountList(wallet);
|
||||
}
|
||||
|
||||
@override
|
||||
MoneroSubaddressList getSubaddressList(Object wallet) {
|
||||
return CWMoneroSubaddressList(wallet);
|
||||
}
|
||||
|
||||
@override
|
||||
TransactionHistoryBase getTransactionHistory(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.transactionHistory;
|
||||
}
|
||||
|
||||
@override
|
||||
MoneroWalletDetails getMoneroWalletDetails(Object wallet) {
|
||||
return CWMoneroWalletDetails(wallet);
|
||||
}
|
||||
|
||||
@override
|
||||
int getHeigthByDate({required DateTime date}) {
|
||||
return getMoneroHeigthByDate(date: date);
|
||||
}
|
||||
|
||||
@override
|
||||
TransactionPriority getDefaultTransactionPriority() {
|
||||
return MoneroTransactionPriority.automatic;
|
||||
}
|
||||
MoneroAccountList getAccountList(Object wallet) {
|
||||
return CWMoneroAccountList(wallet);
|
||||
}
|
||||
|
||||
@override
|
||||
TransactionPriority getMoneroTransactionPrioritySlow()
|
||||
=> MoneroTransactionPriority.slow;
|
||||
MoneroSubaddressList getSubaddressList(Object wallet) {
|
||||
return CWMoneroSubaddressList(wallet);
|
||||
}
|
||||
|
||||
@override
|
||||
TransactionPriority getMoneroTransactionPriorityAutomatic()
|
||||
=> MoneroTransactionPriority.automatic;
|
||||
TransactionHistoryBase getTransactionHistory(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.transactionHistory;
|
||||
}
|
||||
|
||||
@override
|
||||
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
|
||||
return MoneroTransactionPriority.deserialize(raw: raw);
|
||||
}
|
||||
@override
|
||||
MoneroWalletDetails getMoneroWalletDetails(Object wallet) {
|
||||
return CWMoneroWalletDetails(wallet);
|
||||
}
|
||||
|
||||
@override
|
||||
List<TransactionPriority> getTransactionPriorities() {
|
||||
return MoneroTransactionPriority.all;
|
||||
}
|
||||
@override
|
||||
int getHeigthByDate({required DateTime date}) {
|
||||
return getMoneroHeigthByDate(date: date);
|
||||
}
|
||||
|
||||
@override
|
||||
List<String> getMoneroWordList(String language) {
|
||||
switch (language.toLowerCase()) {
|
||||
case 'english':
|
||||
return EnglishMnemonics.words;
|
||||
case 'chinese (simplified)':
|
||||
return ChineseSimplifiedMnemonics.words;
|
||||
case 'dutch':
|
||||
return DutchMnemonics.words;
|
||||
case 'german':
|
||||
return GermanMnemonics.words;
|
||||
case 'japanese':
|
||||
return JapaneseMnemonics.words;
|
||||
case 'portuguese':
|
||||
return PortugueseMnemonics.words;
|
||||
case 'russian':
|
||||
return RussianMnemonics.words;
|
||||
case 'spanish':
|
||||
return SpanishMnemonics.words;
|
||||
case 'french':
|
||||
return FrenchMnemonics.words;
|
||||
case 'italian':
|
||||
return ItalianMnemonics.words;
|
||||
default:
|
||||
return EnglishMnemonics.words;
|
||||
}
|
||||
}
|
||||
@override
|
||||
TransactionPriority getDefaultTransactionPriority() {
|
||||
return MoneroTransactionPriority.automatic;
|
||||
}
|
||||
|
||||
@override
|
||||
WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
|
||||
required String name,
|
||||
required String spendKey,
|
||||
required String viewKey,
|
||||
required String address,
|
||||
required String password,
|
||||
required String language,
|
||||
required int height}) {
|
||||
return MoneroRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
spendKey: spendKey,
|
||||
viewKey: viewKey,
|
||||
address: address,
|
||||
password: password,
|
||||
language: language,
|
||||
height: height);
|
||||
}
|
||||
|
||||
@override
|
||||
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({
|
||||
required String name,
|
||||
required String password,
|
||||
required int height,
|
||||
required String mnemonic}) {
|
||||
return MoneroRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
height: height,
|
||||
mnemonic: mnemonic);
|
||||
}
|
||||
@override
|
||||
TransactionPriority getMoneroTransactionPrioritySlow() => MoneroTransactionPriority.slow;
|
||||
|
||||
@override
|
||||
WalletCredentials createMoneroNewWalletCredentials({
|
||||
@override
|
||||
TransactionPriority getMoneroTransactionPriorityAutomatic() =>
|
||||
MoneroTransactionPriority.automatic;
|
||||
|
||||
@override
|
||||
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
|
||||
return MoneroTransactionPriority.deserialize(raw: raw);
|
||||
}
|
||||
|
||||
@override
|
||||
List<TransactionPriority> getTransactionPriorities() {
|
||||
return MoneroTransactionPriority.all;
|
||||
}
|
||||
|
||||
@override
|
||||
List<String> getMoneroWordList(String language) {
|
||||
switch (language.toLowerCase()) {
|
||||
case 'english':
|
||||
return EnglishMnemonics.words;
|
||||
case 'chinese (simplified)':
|
||||
return ChineseSimplifiedMnemonics.words;
|
||||
case 'dutch':
|
||||
return DutchMnemonics.words;
|
||||
case 'german':
|
||||
return GermanMnemonics.words;
|
||||
case 'japanese':
|
||||
return JapaneseMnemonics.words;
|
||||
case 'portuguese':
|
||||
return PortugueseMnemonics.words;
|
||||
case 'russian':
|
||||
return RussianMnemonics.words;
|
||||
case 'spanish':
|
||||
return SpanishMnemonics.words;
|
||||
case 'french':
|
||||
return FrenchMnemonics.words;
|
||||
case 'italian':
|
||||
return ItalianMnemonics.words;
|
||||
default:
|
||||
return EnglishMnemonics.words;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
WalletCredentials createMoneroRestoreWalletFromKeysCredentials(
|
||||
{required String name,
|
||||
required String spendKey,
|
||||
required String viewKey,
|
||||
required String address,
|
||||
required String password,
|
||||
required String language,
|
||||
required int height}) {
|
||||
return MoneroRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
spendKey: spendKey,
|
||||
viewKey: viewKey,
|
||||
address: address,
|
||||
password: password,
|
||||
language: language,
|
||||
height: height);
|
||||
}
|
||||
|
||||
@override
|
||||
WalletCredentials createMoneroRestoreWalletFromSeedCredentials(
|
||||
{required String name,
|
||||
required String password,
|
||||
required int height,
|
||||
required String mnemonic}) {
|
||||
return MoneroRestoreWalletFromSeedCredentials(
|
||||
name: name, password: password, height: height, mnemonic: mnemonic);
|
||||
}
|
||||
|
||||
@override
|
||||
WalletCredentials createMoneroNewWalletCredentials({
|
||||
required String name,
|
||||
required String language,
|
||||
String? password,}) {
|
||||
return MoneroNewWalletCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
language: language);
|
||||
}
|
||||
String? password,
|
||||
}) {
|
||||
return MoneroNewWalletCredentials(name: name, password: password, language: language);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, String> getKeys(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
final keys = moneroWallet.keys;
|
||||
return <String, String>{
|
||||
'privateSpendKey': keys.privateSpendKey,
|
||||
@override
|
||||
Map<String, String> getKeys(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
final keys = moneroWallet.keys;
|
||||
return <String, String>{
|
||||
'privateSpendKey': keys.privateSpendKey,
|
||||
'privateViewKey': keys.privateViewKey,
|
||||
'publicSpendKey': keys.publicSpendKey,
|
||||
'publicViewKey': keys.publicViewKey};
|
||||
}
|
||||
'publicViewKey': keys.publicViewKey
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Object createMoneroTransactionCreationCredentials({
|
||||
required List<Output> outputs,
|
||||
required TransactionPriority priority}) {
|
||||
return MoneroTransactionCreationCredentials(
|
||||
outputs: outputs.map((out) => OutputInfo(
|
||||
fiatAmount: out.fiatAmount,
|
||||
cryptoAmount: out.cryptoAmount,
|
||||
address: out.address,
|
||||
note: out.note,
|
||||
sendAll: out.sendAll,
|
||||
extractedAddress: out.extractedAddress,
|
||||
isParsedAddress: out.isParsedAddress,
|
||||
formattedCryptoAmount: out.formattedCryptoAmount))
|
||||
.toList(),
|
||||
priority: priority as MoneroTransactionPriority);
|
||||
}
|
||||
@override
|
||||
Object createMoneroTransactionCreationCredentials(
|
||||
{required List<Output> outputs, required TransactionPriority priority}) {
|
||||
return MoneroTransactionCreationCredentials(
|
||||
outputs: outputs
|
||||
.map((out) => OutputInfo(
|
||||
fiatAmount: out.fiatAmount,
|
||||
cryptoAmount: out.cryptoAmount,
|
||||
address: out.address,
|
||||
note: out.note,
|
||||
sendAll: out.sendAll,
|
||||
extractedAddress: out.extractedAddress,
|
||||
isParsedAddress: out.isParsedAddress,
|
||||
formattedCryptoAmount: out.formattedCryptoAmount))
|
||||
.toList(),
|
||||
priority: priority as MoneroTransactionPriority);
|
||||
}
|
||||
|
||||
@override
|
||||
Object createMoneroTransactionCreationCredentialsRaw({
|
||||
required List<OutputInfo> outputs,
|
||||
required TransactionPriority priority}) {
|
||||
return MoneroTransactionCreationCredentials(
|
||||
outputs: outputs,
|
||||
priority: priority as MoneroTransactionPriority);
|
||||
}
|
||||
@override
|
||||
Object createMoneroTransactionCreationCredentialsRaw(
|
||||
{required List<OutputInfo> outputs, required TransactionPriority priority}) {
|
||||
return MoneroTransactionCreationCredentials(
|
||||
outputs: outputs, priority: priority as MoneroTransactionPriority);
|
||||
}
|
||||
|
||||
@override
|
||||
String formatterMoneroAmountToString({required int amount}) {
|
||||
return moneroAmountToString(amount: amount);
|
||||
}
|
||||
@override
|
||||
String formatterMoneroAmountToString({required int amount}) {
|
||||
return moneroAmountToString(amount: amount);
|
||||
}
|
||||
|
||||
@override
|
||||
double formatterMoneroAmountToDouble({required int amount}) {
|
||||
return moneroAmountToDouble(amount: amount);
|
||||
}
|
||||
@override
|
||||
double formatterMoneroAmountToDouble({required int amount}) {
|
||||
return moneroAmountToDouble(amount: amount);
|
||||
}
|
||||
|
||||
@override
|
||||
int formatterMoneroParseAmount({required String amount}) {
|
||||
return moneroParseAmount(amount: amount);
|
||||
}
|
||||
@override
|
||||
int formatterMoneroParseAmount({required String amount}) {
|
||||
return moneroParseAmount(amount: amount);
|
||||
}
|
||||
|
||||
@override
|
||||
Account getCurrentAccount(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
final acc = moneroWallet.walletAddresses.account;
|
||||
return Account(id: acc!.id, label: acc.label, balance: acc.balance);
|
||||
}
|
||||
@override
|
||||
Account getCurrentAccount(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
final acc = moneroWallet.walletAddresses.account;
|
||||
return Account(id: acc!.id, label: acc.label, balance: acc.balance);
|
||||
}
|
||||
|
||||
@override
|
||||
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, balance: balance);
|
||||
}
|
||||
@override
|
||||
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, balance: balance);
|
||||
}
|
||||
|
||||
@override
|
||||
void onStartup() {
|
||||
monero_wallet_api.onStartup();
|
||||
}
|
||||
@override
|
||||
void onStartup() {
|
||||
monero_wallet_api.onStartup();
|
||||
}
|
||||
|
||||
@override
|
||||
int getTransactionInfoAccountId(TransactionInfo tx) {
|
||||
final moneroTransactionInfo = tx as MoneroTransactionInfo;
|
||||
return moneroTransactionInfo.accountIndex;
|
||||
}
|
||||
@override
|
||||
int getTransactionInfoAccountId(TransactionInfo tx) {
|
||||
final moneroTransactionInfo = tx as MoneroTransactionInfo;
|
||||
return moneroTransactionInfo.accountIndex;
|
||||
}
|
||||
|
||||
@override
|
||||
WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource) {
|
||||
return MoneroWalletService(walletInfoSource);
|
||||
}
|
||||
@override
|
||||
WalletService createMoneroWalletService(
|
||||
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
|
||||
return MoneroWalletService(walletInfoSource, unspentCoinSource);
|
||||
}
|
||||
|
||||
@override
|
||||
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.getTransactionAddress(accountIndex, addressIndex);
|
||||
}
|
||||
@override
|
||||
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.getTransactionAddress(accountIndex, addressIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.getSubaddressLabel(accountIndex, addressIndex);
|
||||
}
|
||||
@override
|
||||
String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.getSubaddressLabel(accountIndex, addressIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, String> pendingTransactionInfo(Object transaction) {
|
||||
final ptx = transaction as PendingMoneroTransaction;
|
||||
return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey};
|
||||
}
|
||||
@override
|
||||
Map<String, String> pendingTransactionInfo(Object transaction) {
|
||||
final ptx = transaction as PendingMoneroTransaction;
|
||||
return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Unspent> getUnspents(Object wallet) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
return moneroWallet.unspentCoins
|
||||
.map((MoneroUnspent moneroUnspent) => Unspent(moneroUnspent.address, moneroUnspent.hash,
|
||||
moneroUnspent.value, 0, moneroUnspent.keyImage))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
void updateUnspents(Object wallet) async {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
await moneroWallet.updateUnspent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ class Palette {
|
|||
static const Color nightBlue = Color.fromRGBO(46, 57, 96, 1.0);
|
||||
static const Color moderateOrangeYellow = Color.fromRGBO(245, 134, 82, 1.0);
|
||||
static const Color moderateOrange = Color.fromRGBO(235, 117, 63, 1.0);
|
||||
static const Color moneroOrange = Color.fromRGBO(255, 102, 0, 1.0);
|
||||
static const Color moneroLightOrange = Color.fromRGBO(250, 240, 246, 1.0);
|
||||
static const Color bitcoinOrange = Color.fromRGBO(242, 169, 0, 1.0);
|
||||
static const Color shineGreen = Color.fromRGBO(76, 189, 87, 1.0);
|
||||
static const Color moderateGreen = Color.fromRGBO(45, 158, 56, 1.0);
|
||||
static const Color cornflower = Color.fromRGBO(85, 147, 240, 1.0);
|
||||
|
@ -48,6 +51,7 @@ class Palette {
|
|||
static const Color paleCornflowerBlue = Color.fromRGBO(185, 196, 237, 1.0);
|
||||
static const Color manatee = Color.fromRGBO(153, 161, 176, 1.0);
|
||||
static const Color stateGray = Color.fromRGBO(68, 74, 89, 1.0);
|
||||
static const Color highContrastGray = Color.fromRGBO(76, 76, 76, 1.0);
|
||||
static const Color frostySky = Color.fromRGBO(0, 184, 250, 1.0);
|
||||
}
|
||||
|
||||
|
@ -90,4 +94,7 @@ class PaletteDark {
|
|||
static const Color lightPurpleBlue = Color.fromRGBO(120, 133, 170, 1.0);
|
||||
static const Color indicatorVioletBlue = Color.fromRGBO(59, 72, 119, 1.0);
|
||||
static const Color granite = Color.fromRGBO(48, 51, 60, 1.0);
|
||||
}
|
||||
static const Color matrixGreen = Color.fromRGBO(18, 229, 90, 1.0);
|
||||
static const Color moneroOrange = Color.fromRGBO(255, 102, 0, 1.0);
|
||||
static const Color moneroCard = Color.fromRGBO(20, 21, 24, 1.0);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ import 'package:cake_wallet/routes.dart';
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/di.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/exchange/trade.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
@ -80,7 +79,6 @@ import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_c
|
|||
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
|
||||
import 'package:cake_wallet/src/screens/contact/contact_page.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
|
||||
import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_details.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
||||
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
|
||||
import 'package:cake_wallet/src/screens/faq/faq_page.dart';
|
||||
|
@ -398,16 +396,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
builder: (_) =>
|
||||
getIt.get<BuyWebViewPage>(param1: args));
|
||||
|
||||
case Routes.restoreWalletFromSeedDetails:
|
||||
final args = settings.arguments as List;
|
||||
final walletRestorationFromSeedVM =
|
||||
getIt.get<WalletRestorationFromSeedVM>(param1: args);
|
||||
|
||||
return CupertinoPageRoute<void>(
|
||||
fullscreenDialog: true,
|
||||
builder: (_) => RestoreWalletFromSeedDetailsPage(
|
||||
walletRestorationFromSeedVM: walletRestorationFromSeedVM));
|
||||
|
||||
case Routes.exchange:
|
||||
return CupertinoPageRoute<void>(
|
||||
fullscreenDialog: true,
|
||||
|
|
|
@ -30,7 +30,6 @@ class Routes {
|
|||
static const tradeDetails = '/trade_details';
|
||||
static const exchangeFunds = '/exchange_funds';
|
||||
static const exchangeTrade = '/exchange_trade';
|
||||
static const restoreWalletFromSeedDetails = '/restore_from_seed_details';
|
||||
static const exchange = '/exchange';
|
||||
static const settings = '/settings';
|
||||
static const desktop_settings_page = '/desktop_settings_page';
|
||||
|
|
|
@ -42,10 +42,9 @@ class _AnonpayDetailsPageBodyState extends State<AnonpayDetailsPageBody> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SectionStandardList(
|
||||
context: context,
|
||||
sectionCount: 1,
|
||||
itemCounter: (int _) => widget.anonpayDetailsViewModel.items.length,
|
||||
itemBuilder: (_, __, index) {
|
||||
itemBuilder: (__, index) {
|
||||
final item = widget.anonpayDetailsViewModel.items[index];
|
||||
|
||||
if (item is DetailsListStatusItem) {
|
||||
|
|
|
@ -80,7 +80,7 @@ class BackupPage extends BasePage {
|
|||
isLoading: backupViewModelBase.state is IsExecutingState,
|
||||
onPressed: () => onExportBackup(context),
|
||||
text: S.of(context).export_backup,
|
||||
color: Theme.of(context).accentTextTheme.bodyLarge!.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
|
@ -127,9 +127,9 @@ class BackupPage extends BasePage {
|
|||
builder: (dialogContext) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context).export_backup,
|
||||
alertContent: 'Please select destination for the backup file.',
|
||||
rightButtonText: 'Save to Downloads',
|
||||
leftButtonText: 'Share',
|
||||
alertContent: S.of(context).select_destination,
|
||||
rightButtonText: S.of(context).save_to_downloads,
|
||||
leftButtonText:S.of(context).share,
|
||||
actionRightButton: () async {
|
||||
final permission = await Permission.storage.request();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
|
|||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
|
||||
class EditBackupPasswordPage extends BasePage {
|
||||
EditBackupPasswordPage(this.editBackupPasswordViewModel)
|
||||
|
@ -39,19 +40,13 @@ class EditBackupPasswordPage extends BasePage {
|
|||
controller: textEditingController,
|
||||
style: TextStyle(
|
||||
fontSize: 26,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!)))),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor)))),
|
||||
Positioned(
|
||||
child: Observer(
|
||||
builder: (_) => PrimaryButton(
|
||||
onPressed: () => onSave(context),
|
||||
text: S.of(context).save,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isDisabled: !editBackupPasswordViewModel.canSave)),
|
||||
bottom: 24,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/src/widgets/nav_bar.dart';
|
||||
|
@ -10,22 +9,22 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
enum AppBarStyle { regular, withShadow, transparent }
|
||||
|
||||
abstract class BasePage extends StatelessWidget {
|
||||
BasePage()
|
||||
: _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
BasePage() : _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey;
|
||||
|
||||
final Image closeButtonImage =
|
||||
Image.asset('assets/images/close_button.png');
|
||||
final Image closeButtonImage = Image.asset('assets/images/close_button.png');
|
||||
final Image closeButtonImageDarkTheme =
|
||||
Image.asset('assets/images/close_button_dark_theme.png');
|
||||
Image.asset('assets/images/close_button_dark_theme.png');
|
||||
|
||||
String? get title => null;
|
||||
|
||||
Color get backgroundLightColor => Colors.white;
|
||||
Color? get backgroundLightColor => null;
|
||||
|
||||
Color get backgroundDarkColor => PaletteDark.backgroundColor;
|
||||
Color? get backgroundDarkColor => null;
|
||||
|
||||
Color? get titleColor => null;
|
||||
bool get gradientBackground => false;
|
||||
|
||||
bool get gradientAll => false;
|
||||
|
||||
bool get resizeToAvoidBottomInset => true;
|
||||
|
||||
|
@ -43,15 +42,41 @@ abstract class BasePage extends StatelessWidget {
|
|||
|
||||
void onClose(BuildContext context) => Navigator.of(context).pop();
|
||||
|
||||
Color pageBackgroundColor(BuildContext context) =>
|
||||
(currentTheme.type == ThemeType.dark
|
||||
? backgroundDarkColor
|
||||
: backgroundLightColor) ??
|
||||
(gradientBackground && currentTheme.type == ThemeType.bright
|
||||
? Colors.transparent
|
||||
: Theme.of(context).colorScheme.background);
|
||||
|
||||
Color titleColor(BuildContext context) =>
|
||||
(gradientBackground && currentTheme.type == ThemeType.bright) ||
|
||||
(gradientAll && currentTheme.brightness == Brightness.light)
|
||||
? Colors.white
|
||||
: Theme.of(context).appBarTheme.titleTextStyle!.color!;
|
||||
|
||||
Color? pageIconColor(BuildContext context) => titleColor(context);
|
||||
|
||||
Widget closeButton(BuildContext context) => Image.asset(
|
||||
currentTheme.type == ThemeType.dark
|
||||
? 'assets/images/close_button_dark_theme.png'
|
||||
: 'assets/images/close_button.png',
|
||||
color: pageIconColor(context),
|
||||
height: 16,
|
||||
);
|
||||
|
||||
Widget backButton(BuildContext context) => Icon(
|
||||
Icons.arrow_back_ios,
|
||||
color: pageIconColor(context),
|
||||
size: 16,
|
||||
);
|
||||
|
||||
Widget? leading(BuildContext context) {
|
||||
if (ModalRoute.of(context)?.isFirst ?? true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final _backButton = Icon(Icons.arrow_back_ios,
|
||||
color: titleColor ?? Theme.of(context).primaryTextTheme!.titleLarge!.color!,
|
||||
size: 16,);
|
||||
|
||||
return MergeSemantics(
|
||||
child: SizedBox(
|
||||
height: 37,
|
||||
|
@ -66,7 +91,7 @@ abstract class BasePage extends StatelessWidget {
|
|||
(states) => Colors.transparent),
|
||||
),
|
||||
onPressed: () => onClose(context),
|
||||
child: _backButton,
|
||||
child: backButton(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -83,8 +108,7 @@ abstract class BasePage extends StatelessWidget {
|
|||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Lato',
|
||||
color: titleColor ??
|
||||
Theme.of(context).primaryTextTheme!.titleLarge!.color!),
|
||||
color: titleColor(context)),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -93,9 +117,8 @@ abstract class BasePage extends StatelessWidget {
|
|||
Widget? floatingActionButton(BuildContext context) => null;
|
||||
|
||||
ObstructingPreferredSizeWidget appBar(BuildContext context) {
|
||||
final appBarColor = currentTheme.type == ThemeType.dark
|
||||
? backgroundDarkColor : backgroundLightColor;
|
||||
|
||||
final appBarColor = pageBackgroundColor(context);
|
||||
|
||||
switch (appBarStyle) {
|
||||
case AppBarStyle.regular:
|
||||
// FIX-ME: NavBar no context
|
||||
|
@ -139,12 +162,9 @@ abstract class BasePage extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _backgroundColor = currentTheme.type == ThemeType.dark
|
||||
? backgroundDarkColor : backgroundLightColor;
|
||||
|
||||
final root = Scaffold(
|
||||
key: _scaffoldKey,
|
||||
backgroundColor: _backgroundColor,
|
||||
backgroundColor: pageBackgroundColor(context),
|
||||
resizeToAvoidBottomInset: resizeToAvoidBottomInset,
|
||||
extendBodyBehindAppBar: extendBodyBehindAppBar,
|
||||
endDrawer: endDrawer,
|
||||
|
|
|
@ -24,9 +24,6 @@ class BuyWebViewPage extends BasePage {
|
|||
@override
|
||||
Color get backgroundDarkColor => Colors.white;
|
||||
|
||||
@override
|
||||
Color get titleColor => Palette.darkBlueCraiola;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) =>
|
||||
BuyWebViewPageBody(buyViewModel, ordersStore: ordersStore, url: url);
|
||||
|
|
|
@ -3,6 +3,10 @@ import 'package:cake_wallet/buy/buy_provider.dart';
|
|||
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/src/screens/buy/widgets/buy_list_item.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
|
@ -58,9 +62,6 @@ class PreOrderPage extends BasePage {
|
|||
@override
|
||||
String get title => S.current.buy + ' ' + walletTypeToString(buyViewModel.wallet.type);
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.white;
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
||||
|
@ -80,10 +81,7 @@ class PreOrderPage extends BasePage {
|
|||
return KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.backgroundColor!,
|
||||
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
|
@ -104,10 +102,8 @@ class PreOrderPage extends BasePage {
|
|||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24)),
|
||||
gradient: LinearGradient(colors: [
|
||||
Theme.of(context).primaryTextTheme!.titleMedium!.color!,
|
||||
Theme.of(context)
|
||||
.primaryTextTheme!.titleMedium!
|
||||
.decorationColor!,
|
||||
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
|
||||
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
|
||||
], begin: Alignment.topLeft, end: Alignment.bottomRight),
|
||||
),
|
||||
child: Padding(
|
||||
|
@ -162,11 +158,11 @@ class PreOrderPage extends BasePage {
|
|||
),
|
||||
),
|
||||
hintText: '0.00',
|
||||
borderColor: Theme.of(context).primaryTextTheme!.bodyLarge!.decorationColor!,
|
||||
borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
|
||||
borderWidth: 0.5,
|
||||
textStyle: TextStyle(fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
|
||||
placeholderTextStyle: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme!.headlineSmall!.decorationColor!,
|
||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 36,
|
||||
),
|
||||
|
@ -181,7 +177,7 @@ class PreOrderPage extends BasePage {
|
|||
S.of(context).buy_with + ':',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.titleLarge!.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
|
@ -248,7 +244,7 @@ class PreOrderPage extends BasePage {
|
|||
? S.of(context).buy
|
||||
: S.of(context).buy_with +
|
||||
' ${buyViewModel.selectedProvider!.description.title}',
|
||||
color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isLoading: buyViewModel.isRunning,
|
||||
isDisabled: (buyViewModel.selectedProvider == null) ||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:cake_wallet/core/auth_service.dart';
|
||||
import 'package:cake_wallet/entities/contact_base.dart';
|
||||
import 'package:cake_wallet/entities/contact_record.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -32,13 +34,13 @@ class ContactListPage extends BasePage {
|
|||
height: 32.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).accentTextTheme!.bodySmall!.color!),
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.buttonBackgroundColor),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Icons.add,
|
||||
color: Theme.of(context).primaryTextTheme.titleLarge!.color!,
|
||||
color: Theme.of(context).appBarTheme.titleTextStyle!.color,
|
||||
size: 22.0,
|
||||
),
|
||||
ButtonTheme(
|
||||
|
@ -48,17 +50,15 @@ class ContactListPage extends BasePage {
|
|||
// FIX-ME: Style
|
||||
//shape: CircleBorder(),
|
||||
onPressed: () async {
|
||||
if (contactListViewModel
|
||||
.shouldRequireTOTP2FAForAddingContacts) {
|
||||
if (contactListViewModel.shouldRequireTOTP2FAForAddingContacts) {
|
||||
authService.authenticateAction(
|
||||
context,
|
||||
route: Routes.addressBookAddContact,
|
||||
conditionToDetermineIfToUse2FA: contactListViewModel
|
||||
.shouldRequireTOTP2FAForAddingContacts,
|
||||
conditionToDetermineIfToUse2FA:
|
||||
contactListViewModel.shouldRequireTOTP2FAForAddingContacts,
|
||||
);
|
||||
} else {
|
||||
await Navigator.of(context)
|
||||
.pushNamed(Routes.addressBookAddContact);
|
||||
await Navigator.of(context).pushNamed(Routes.addressBookAddContact);
|
||||
}
|
||||
},
|
||||
child: Offstage()),
|
||||
|
@ -72,17 +72,13 @@ class ContactListPage extends BasePage {
|
|||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
|
||||
padding: EdgeInsets.all(20.0),
|
||||
child: Observer(builder: (_) {
|
||||
final contacts = contactListViewModel.contactsToShow;
|
||||
final walletContacts = contactListViewModel.walletContactsToShow;
|
||||
return CollapsibleSectionList(
|
||||
context: context,
|
||||
sectionCount: 2,
|
||||
themeColor: Theme.of(context).primaryTextTheme.titleLarge!.color!,
|
||||
dividerThemeColor:
|
||||
Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!,
|
||||
sectionTitleBuilder: (_, int sectionIndex) {
|
||||
sectionTitleBuilder: (int sectionIndex) {
|
||||
var title = S.current.contact_list_contacts;
|
||||
|
||||
if (sectionIndex == 0) {
|
||||
|
@ -95,7 +91,7 @@ class ContactListPage extends BasePage {
|
|||
},
|
||||
itemCounter: (int sectionIndex) =>
|
||||
sectionIndex == 0 ? walletContacts.length : contacts.length,
|
||||
itemBuilder: (_, sectionIndex, index) {
|
||||
itemBuilder: (int sectionIndex, index) {
|
||||
if (sectionIndex == 0) {
|
||||
final walletInfo = walletContacts[index];
|
||||
return generateRaw(context, walletInfo);
|
||||
|
@ -128,8 +124,7 @@ class ContactListPage extends BasePage {
|
|||
return;
|
||||
}
|
||||
|
||||
final isCopied = await showNameAndAddressDialog(
|
||||
context, contact.name, contact.address);
|
||||
final isCopied = await showNameAndAddressDialog(context, contact.name, contact.address);
|
||||
|
||||
if (isCopied) {
|
||||
await Clipboard.setData(ClipboardData(text: contact.address));
|
||||
|
@ -137,7 +132,6 @@ class ContactListPage extends BasePage {
|
|||
}
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: const EdgeInsets.only(top: 16, bottom: 16, right: 24),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -152,7 +146,7 @@ class ContactListPage extends BasePage {
|
|||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).primaryTextTheme.titleLarge!.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
),
|
||||
),
|
||||
))
|
||||
|
@ -177,8 +171,7 @@ class ContactListPage extends BasePage {
|
|||
false;
|
||||
}
|
||||
|
||||
Future<bool> showNameAndAddressDialog(
|
||||
BuildContext context, String name, String address) async {
|
||||
Future<bool> showNameAndAddressDialog(BuildContext context, String name, String address) async {
|
||||
return await showPopUp<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
|
@ -193,8 +186,7 @@ class ContactListPage extends BasePage {
|
|||
false;
|
||||
}
|
||||
|
||||
ActionPane _actionPane(BuildContext context, ContactRecord contact) =>
|
||||
ActionPane(
|
||||
ActionPane _actionPane(BuildContext context, ContactRecord contact) => ActionPane(
|
||||
motion: const ScrollMotion(),
|
||||
extentRatio: 0.4,
|
||||
children: [
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:cake_wallet/core/address_validator.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cw_core/currency.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -17,6 +18,8 @@ import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
|||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
||||
import 'package:cake_wallet/themes/extensions/address_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
|
||||
class ContactPage extends BasePage {
|
||||
ContactPage(this.contactViewModel)
|
||||
|
@ -47,7 +50,7 @@ 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!.labelSmall!.color!,
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
|
||||
height: 8);
|
||||
|
||||
reaction((_) => contactViewModel.state, (ExecutionState state) {
|
||||
|
@ -99,15 +102,9 @@ class ContactPage extends BasePage {
|
|||
AddressTextFieldOption.paste,
|
||||
AddressTextFieldOption.qrCode,
|
||||
],
|
||||
buttonColor: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displaySmall!
|
||||
.color!,
|
||||
buttonColor: Theme.of(context).extension<AddressTheme>()!.actionButtonColor,
|
||||
iconColor: PaletteDark.gray,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.backgroundColor!,
|
||||
borderColor: Theme.of(context).extension<CakeTextTheme>()!.textfieldUnderlineColor,
|
||||
validator:
|
||||
AddressValidator(type: contactViewModel.currency!),
|
||||
),
|
||||
|
@ -143,10 +140,7 @@ class ContactPage extends BasePage {
|
|||
await contactViewModel.save();
|
||||
},
|
||||
text: S.of(context).save,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isDisabled: !contactViewModel.isReady)))
|
||||
],
|
||||
|
|
|
@ -4,6 +4,8 @@ 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/src/widgets/gradient_background.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/utils/device_info.dart';
|
||||
import 'package:cake_wallet/utils/version_comparator.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
|
||||
|
@ -11,7 +13,6 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
import 'package:cake_wallet/routes.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/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -29,6 +30,8 @@ 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/src/screens/release_notes/release_notes_screen.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
|
||||
class DashboardPage extends StatelessWidget {
|
||||
DashboardPage({
|
||||
|
@ -81,28 +84,11 @@ class _DashboardPageView extends BasePage {
|
|||
final BalancePage balancePage;
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor =>
|
||||
currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => Colors.transparent;
|
||||
bool get gradientBackground => true;
|
||||
|
||||
@override
|
||||
Widget Function(BuildContext, Widget) get rootWrapper =>
|
||||
(BuildContext context, Widget scaffold) => Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
Theme.of(context).primaryColor,
|
||||
],
|
||||
begin: Alignment.topRight,
|
||||
end: Alignment.bottomLeft,
|
||||
),
|
||||
),
|
||||
child: scaffold,
|
||||
);
|
||||
(BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
@ -122,7 +108,7 @@ class _DashboardPageView extends BasePage {
|
|||
Widget trailing(BuildContext context) {
|
||||
final menuButton = Image.asset(
|
||||
'assets/images/menu.png',
|
||||
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor,
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
|
||||
);
|
||||
|
||||
return Container(
|
||||
|
@ -141,6 +127,7 @@ class _DashboardPageView extends BasePage {
|
|||
|
||||
final DashboardViewModel dashboardViewModel;
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
|
||||
int get initialPage => dashboardViewModel.shouldShowMarketPlaceInDashboard ? 1 : 0;
|
||||
ObservableList<Widget> pages = ObservableList<Widget>();
|
||||
bool _isEffectsInstalled = false;
|
||||
|
@ -199,8 +186,10 @@ class _DashboardPageView extends BasePage {
|
|||
dotWidth: 6.0,
|
||||
dotHeight: 6.0,
|
||||
dotColor: Theme.of(context).indicatorColor,
|
||||
activeDotColor:
|
||||
Theme.of(context).accentTextTheme.headlineMedium!.backgroundColor!,
|
||||
activeDotColor: Theme.of(context)
|
||||
.extension<DashboardPageTheme>()!
|
||||
.indicatorDotTheme
|
||||
.activeIndicatorColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -216,12 +205,11 @@ class _DashboardPageView extends BasePage {
|
|||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(50.0),
|
||||
border: Border.all(
|
||||
color: currentTheme.type == ThemeType.bright
|
||||
? Color.fromRGBO(255, 255, 255, 0.2)
|
||||
: Colors.transparent,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
|
||||
width: 1,
|
||||
),
|
||||
color: Theme.of(context).textTheme.titleLarge!.backgroundColor!,
|
||||
color:
|
||||
Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 32, right: 32),
|
||||
|
@ -240,13 +228,11 @@ class _DashboardPageView extends BasePage {
|
|||
width: 24,
|
||||
color: action.isEnabled?.call(dashboardViewModel) ?? true
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.displayMedium!
|
||||
.backgroundColor!
|
||||
.extension<DashboardPageTheme>()!
|
||||
.mainActionsIconColor
|
||||
: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.displaySmall!
|
||||
.backgroundColor!,
|
||||
.extension<BalancePageTheme>()!
|
||||
.labelTextColor,
|
||||
),
|
||||
title: action.name(context),
|
||||
onClick: () async =>
|
||||
|
@ -254,9 +240,8 @@ class _DashboardPageView extends BasePage {
|
|||
textColor: action.isEnabled?.call(dashboardViewModel) ?? true
|
||||
? null
|
||||
: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.displaySmall!
|
||||
.backgroundColor!,
|
||||
.extension<BalancePageTheme>()!
|
||||
.labelTextColor,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DesktopActionButton extends StatelessWidget {
|
||||
|
@ -30,7 +33,7 @@ class DesktopActionButton extends StatelessWidget {
|
|||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!,
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||
),
|
||||
child: Center(
|
||||
child: Row(
|
||||
|
@ -41,14 +44,8 @@ class DesktopActionButton extends StatelessWidget {
|
|||
height: 30,
|
||||
width: 30,
|
||||
color: isEnabled
|
||||
? Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!
|
||||
: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displaySmall!
|
||||
.backgroundColor!,
|
||||
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
AutoSizeText(
|
||||
|
@ -58,10 +55,7 @@ class DesktopActionButton extends StatelessWidget {
|
|||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
color: isEnabled
|
||||
? Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!
|
||||
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
: null,
|
||||
height: 1,
|
||||
),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
|
||||
class SideMenuItem extends StatelessWidget {
|
||||
const SideMenuItem({
|
||||
|
@ -16,7 +17,7 @@ class SideMenuItem extends StatelessWidget {
|
|||
|
||||
Color _setColor(BuildContext context) {
|
||||
if (isSelected) {
|
||||
return Theme.of(context).primaryTextTheme!.titleLarge!.color!;
|
||||
return Theme.of(context).extension<CakeTextTheme>()!.titleColor;
|
||||
} else {
|
||||
return Theme.of(context).highlightColor;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import 'package:another_flushbar/flushbar.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.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/dashboard/desktop_widgets/dropdown_item_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||
|
@ -38,14 +40,14 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
|
|||
'assets/images/new_wallet.png',
|
||||
height: 12,
|
||||
width: 12,
|
||||
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
);
|
||||
|
||||
Image _restoreWalletImage(BuildContext context) => Image.asset(
|
||||
'assets/images/restore_wallet.png',
|
||||
height: 12,
|
||||
width: 12,
|
||||
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
);
|
||||
|
||||
Flushbar<void>? _progressBar;
|
||||
|
@ -95,8 +97,8 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
|
|||
onChanged: (item) {
|
||||
item?.onSelected();
|
||||
},
|
||||
dropdownColor: themeData.textTheme!.bodyLarge?.decorationColor,
|
||||
style: TextStyle(color: themeData.primaryTextTheme!.titleLarge?.color),
|
||||
dropdownColor: themeData.extension<CakeMenuTheme>()!.backgroundColor,
|
||||
style: TextStyle(color: themeData.extension<CakeTextTheme>()!.titleColor),
|
||||
selectedItemBuilder: (context) => dropDownItems.map((item) => item.child).toList(),
|
||||
value: dropDownItems.firstWhere((element) => element.isSelected),
|
||||
underline: const SizedBox(),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DropDownItemWidget extends StatelessWidget {
|
||||
|
@ -23,7 +24,7 @@ class DropDownItemWidget extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
|||
import 'package:cake_wallet/src/widgets/checkbox_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
|
||||
import 'package:cw_core/erc20_token.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -111,7 +112,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
|||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 28),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).accentTextTheme.bodySmall!.color!,
|
||||
color: Theme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Row(
|
||||
|
@ -128,7 +129,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
|||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).primaryTextTheme.titleLarge!.color!,
|
||||
color: Theme.of(context).dialogTheme.backgroundColor,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
|
@ -138,7 +139,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
|||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).primaryTextTheme.labelSmall!.color!,
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -197,7 +198,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
|
|||
}
|
||||
},
|
||||
text: S.of(context).save,
|
||||
color: Theme.of(context).accentTextTheme.bodyLarge!.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -7,6 +7,8 @@ import 'package:cake_wallet/routes.dart';
|
|||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
|
||||
import 'package:cake_wallet/themes/extensions/address_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
@ -34,7 +36,7 @@ class HomeSettingsPage extends BasePage {
|
|||
onItemSelected: _homeSettingsViewModel.setSortBalanceBy,
|
||||
),
|
||||
),
|
||||
Divider(color: Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!),
|
||||
Divider(color: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor),
|
||||
Observer(
|
||||
builder: (_) => SettingsSwitcherCell(
|
||||
title: S.of(context).pin_at_top(_homeSettingsViewModel.nativeToken.title),
|
||||
|
@ -44,7 +46,7 @@ class HomeSettingsPage extends BasePage {
|
|||
},
|
||||
),
|
||||
),
|
||||
Divider(color: Theme.of(context).primaryTextTheme.bodySmall!.decorationColor!),
|
||||
Divider(color: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
|
@ -53,12 +55,12 @@ class HomeSettingsPage extends BasePage {
|
|||
padding: const EdgeInsetsDirectional.only(start: 16),
|
||||
child: TextFormField(
|
||||
controller: _searchController,
|
||||
style: TextStyle(color: Theme.of(context).primaryTextTheme.titleLarge!.color!),
|
||||
style: TextStyle(color: Theme.of(context).dialogTheme.backgroundColor),
|
||||
decoration: InputDecoration(
|
||||
hintText: S.of(context).search_add_token,
|
||||
prefixIcon: Image.asset("assets/images/search_icon.png"),
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).accentTextTheme.displaySmall!.color!,
|
||||
fillColor: Theme.of(context).extension<AddressTheme>()!.actionButtonColor,
|
||||
alignLabelWithHint: false,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
|
@ -84,15 +86,15 @@ class HomeSettingsPage extends BasePage {
|
|||
});
|
||||
},
|
||||
elevation: 0,
|
||||
fillColor: Theme.of(context).accentTextTheme.bodySmall!.color!,
|
||||
fillColor: Theme.of(context).cardColor,
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Theme.of(context).primaryTextTheme.titleLarge!.color!,
|
||||
color: Theme.of(context).dialogTheme.backgroundColor,
|
||||
size: 22.0,
|
||||
),
|
||||
padding: EdgeInsets.all(12),
|
||||
shape: CircleBorder(),
|
||||
splashColor: Theme.of(context).accentTextTheme.bodySmall!.color!,
|
||||
splashColor: Theme.of(context).cardColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -146,7 +148,7 @@ class HomeSettingsPage extends BasePage {
|
|||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).accentTextTheme.bodySmall!.color!,
|
||||
color: Theme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
|
||||
class ActionButton extends StatelessWidget {
|
||||
ActionButton(
|
||||
|
@ -46,14 +47,11 @@ class ActionButton extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: textColor ??
|
||||
Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!),
|
||||
Theme.of(context).extension<DashboardPageTheme>()!.cardTextColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/entities/receive_page_option.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.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';
|
||||
|
@ -21,6 +25,8 @@ import 'package:keyboard_actions/keyboard_actions.dart';
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
|
||||
class AddressPage extends BasePage {
|
||||
AddressPage({
|
||||
|
@ -48,11 +54,7 @@ class AddressPage extends BasePage {
|
|||
final FocusNode _cryptoAmountFocus;
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor =>
|
||||
currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => Colors.transparent;
|
||||
bool get gradientBackground => true;
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
@ -61,14 +63,6 @@ class AddressPage extends BasePage {
|
|||
|
||||
@override
|
||||
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;
|
||||
|
||||
bool isMobileView = ResponsiveLayoutUtil.instance.isMobile;
|
||||
|
||||
return MergeSemantics(
|
||||
|
@ -84,7 +78,7 @@ class AddressPage extends BasePage {
|
|||
overlayColor: MaterialStateColor.resolveWith((states) => Colors.transparent),
|
||||
),
|
||||
onPressed: () => onClose(context),
|
||||
child: !isMobileView ? _closeButton : _backButton,
|
||||
child: !isMobileView ? closeButton(context) : backButton(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -94,20 +88,11 @@ class AddressPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget middle(BuildContext context) => PresentReceiveOptionPicker(
|
||||
receiveOptionViewModel: receiveOptionViewModel,
|
||||
hasWhiteBackground: currentTheme.type == ThemeType.light,
|
||||
);
|
||||
color: titleColor(context), receiveOptionViewModel: receiveOptionViewModel);
|
||||
|
||||
@override
|
||||
Widget Function(BuildContext, Widget) get rootWrapper =>
|
||||
(BuildContext context, Widget scaffold) => Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
Theme.of(context).primaryColor,
|
||||
], begin: Alignment.topRight, end: Alignment.bottomLeft)),
|
||||
child: scaffold);
|
||||
(BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
|
||||
|
||||
@override
|
||||
Widget? trailing(BuildContext context) {
|
||||
|
@ -125,11 +110,7 @@ class AddressPage extends BasePage {
|
|||
context: context,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.share,
|
||||
size: 20,
|
||||
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
),
|
||||
icon: Icon(Icons.share, size: 20, color: pageIconColor(context)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -166,10 +147,10 @@ class AddressPage extends BasePage {
|
|||
return KeyboardActions(
|
||||
autoScroll: false,
|
||||
disableScroll: true,
|
||||
tapOutsideToDismiss: true,
|
||||
tapOutsideBehavior: TapOutsideBehavior.translucentDismiss,
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme.bodyLarge!.backgroundColor!,
|
||||
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
|
@ -201,8 +182,12 @@ class AddressPage extends BasePage {
|
|||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(25)),
|
||||
border: Border.all(
|
||||
color: Theme.of(context).textTheme.titleMedium!.color!, width: 1),
|
||||
color: Theme.of(context).textTheme.titleLarge!.backgroundColor!),
|
||||
color:
|
||||
Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
|
||||
width: 1),
|
||||
color: Theme.of(context)
|
||||
.extension<SyncIndicatorTheme>()!
|
||||
.syncedBackgroundColor),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
@ -216,14 +201,13 @@ class AddressPage extends BasePage {
|
|||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme.displayMedium!
|
||||
.backgroundColor!),
|
||||
.extension<SyncIndicatorTheme>()!
|
||||
.textColor),
|
||||
)),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
color:
|
||||
Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.textColor,
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -234,8 +218,7 @@ class AddressPage extends BasePage {
|
|||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color:
|
||||
Theme.of(context).accentTextTheme.displaySmall!.backgroundColor!));
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor));
|
||||
} else {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
|
||||
class AnonpayTransactionRow extends StatelessWidget {
|
||||
AnonpayTransactionRow({
|
||||
|
@ -37,19 +39,19 @@ class AnonpayTransactionRow extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)),
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor)),
|
||||
Text(amount + ' ' + currency,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!))
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor))
|
||||
]),
|
||||
SizedBox(height: 5),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
|
||||
Text(createdAt,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).textTheme!.labelSmall!.backgroundColor!))
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
|
||||
])
|
||||
],
|
||||
))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/utils/feature_flag.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -10,6 +10,8 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
|||
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';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
|
||||
|
||||
class BalancePage extends StatelessWidget {
|
||||
BalancePage({required this.dashboardViewModel, required this.settingsStore});
|
||||
|
@ -41,7 +43,8 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
color:
|
||||
Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
|
||||
height: 1,
|
||||
),
|
||||
maxLines: 1,
|
||||
|
@ -55,8 +58,9 @@ class BalancePage extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(8.0),
|
||||
child: Image.asset(
|
||||
'assets/images/home_screen_settings_icon.png',
|
||||
color:
|
||||
Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
color: Theme.of(context)
|
||||
.extension<DashboardPageTheme>()!
|
||||
.pageTitleTextColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -72,9 +76,7 @@ class BalancePage extends StatelessWidget {
|
|||
return IntroducingCard(
|
||||
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,
|
||||
borderColor: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
|
||||
closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard);
|
||||
}
|
||||
return Container();
|
||||
|
@ -134,12 +136,10 @@ class BalancePage extends StatelessWidget {
|
|||
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,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
|
||||
width: 1,
|
||||
),
|
||||
color: Theme.of(context).textTheme.titleLarge!.backgroundColor!,
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||
),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
|
||||
|
@ -164,9 +164,8 @@ class BalancePage extends StatelessWidget {
|
|||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displaySmall!
|
||||
.backgroundColor!,
|
||||
.extension<BalancePageTheme>()!
|
||||
.labelTextColor,
|
||||
height: 1)),
|
||||
if (hasAdditionalBalance)
|
||||
Padding(
|
||||
|
@ -174,9 +173,8 @@ class BalancePage extends StatelessWidget {
|
|||
child: Icon(Icons.help_outline,
|
||||
size: 16,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displaySmall!
|
||||
.backgroundColor!),
|
||||
.extension<BalancePageTheme>()!
|
||||
.labelTextColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -187,9 +185,8 @@ class BalancePage extends StatelessWidget {
|
|||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!,
|
||||
.extension<BalancePageTheme>()!
|
||||
.balanceAmountColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.start),
|
||||
|
@ -200,10 +197,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
|
||||
height: 1)),
|
||||
],
|
||||
),
|
||||
|
@ -213,7 +207,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 28,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.assetTitleColor,
|
||||
height: 1)),
|
||||
],
|
||||
),
|
||||
|
@ -229,7 +223,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).accentTextTheme.displaySmall!.backgroundColor!,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
|
@ -240,7 +234,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 20,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
||||
height: 1,
|
||||
),
|
||||
maxLines: 1,
|
||||
|
@ -254,7 +248,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
|
@ -272,7 +266,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).accentTextTheme.displaySmall!.backgroundColor!,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
|
@ -283,7 +277,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 20,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.assetTitleColor,
|
||||
height: 1,
|
||||
),
|
||||
maxLines: 1,
|
||||
|
@ -297,7 +291,7 @@ class BalancePage extends StatelessWidget {
|
|||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).accentTextTheme.displayMedium!.backgroundColor!,
|
||||
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||
|
@ -36,9 +37,6 @@ class DateSectionRaw extends StatelessWidget {
|
|||
child: Text(title,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context)
|
||||
.textTheme!
|
||||
.labelSmall!
|
||||
.backgroundColor!)));
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.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/themes/extensions/menu_theme.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:flutter/material.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;
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
|
||||
class FilterWidget extends StatelessWidget {
|
||||
FilterWidget({required this.dashboardViewModel});
|
||||
|
@ -15,7 +18,7 @@ class FilterWidget extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const sectionDivider = const SectionDivider();
|
||||
const sectionDivider = const HorizontalSectionDivider();
|
||||
return PickerWrapperWidget(
|
||||
children: [
|
||||
Padding(
|
||||
|
@ -23,7 +26,7 @@ class FilterWidget extends StatelessWidget {
|
|||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(24)),
|
||||
child: Container(
|
||||
color: Theme.of(context).textTheme!.bodyLarge!.decorationColor!,
|
||||
color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
@ -32,10 +35,7 @@ class FilterWidget extends StatelessWidget {
|
|||
child: Text(
|
||||
S.of(context).filter_by,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.labelSmall!
|
||||
.color!,
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
|
@ -63,10 +63,7 @@ class FilterWidget extends StatelessWidget {
|
|||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart';
|
||||
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
|
||||
class HeaderRow extends StatelessWidget {
|
||||
HeaderRow({required this.dashboardViewModel});
|
||||
|
@ -12,7 +14,7 @@ class HeaderRow extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final filterIcon = Image.asset('assets/images/filter_icon.png',
|
||||
color: Theme.of(context).textTheme!.bodySmall!.decorationColor!);
|
||||
color: Theme.of(context).extension<FilterTheme>()!.iconColor);
|
||||
|
||||
return Container(
|
||||
height: 52,
|
||||
|
@ -27,10 +29,7 @@ class HeaderRow extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!),
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
|
@ -45,7 +44,7 @@ class HeaderRow extends StatelessWidget {
|
|||
width: 36,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).textTheme!.labelSmall!.color!),
|
||||
color: Theme.of(context).extension<FilterTheme>()!.buttonColor),
|
||||
child: filterIcon,
|
||||
),
|
||||
)
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
|
||||
class MarketPlacePage extends StatelessWidget {
|
||||
MarketPlacePage({
|
||||
|
@ -40,10 +41,7 @@ class MarketPlacePage extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!,
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import 'package:cake_wallet/src/widgets/setting_action_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/setting_actions.dart';
|
||||
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
// FIXME: terrible design.
|
||||
|
||||
class MenuWidget extends StatefulWidget {
|
||||
MenuWidget(this.dashboardViewModel);
|
||||
|
||||
|
@ -19,19 +18,19 @@ class MenuWidget extends StatefulWidget {
|
|||
|
||||
class MenuWidgetState extends State<MenuWidget> {
|
||||
MenuWidgetState()
|
||||
: this.menuWidth = 0,
|
||||
this.screenWidth = 0,
|
||||
this.screenHeight = 0,
|
||||
this.headerHeight = 120,
|
||||
this.tileHeight = 60,
|
||||
this.fromTopEdge = 50,
|
||||
this.fromBottomEdge = 25,
|
||||
this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
|
||||
this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
|
||||
this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
|
||||
this.havenIcon = Image.asset('assets/images/haven_menu.png'),
|
||||
this.ethereumIcon = Image.asset('assets/images/eth_icon.png'),
|
||||
this.bitcoinCashIcon = Image.asset('assets/images/bch_icon.png');
|
||||
: this.menuWidth = 0,
|
||||
this.screenWidth = 0,
|
||||
this.screenHeight = 0,
|
||||
this.headerHeight = 120,
|
||||
this.tileHeight = 60,
|
||||
this.fromTopEdge = 50,
|
||||
this.fromBottomEdge = 25,
|
||||
this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
|
||||
this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
|
||||
this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
|
||||
this.havenIcon = Image.asset('assets/images/haven_menu.png'),
|
||||
this.ethereumIcon = Image.asset('assets/images/eth_icon.png'),
|
||||
this.bitcoinCashIcon = Image.asset('assets/images/bch_icon.png');
|
||||
|
||||
final largeScreen = 731;
|
||||
|
||||
|
@ -88,121 +87,111 @@ class MenuWidgetState extends State<MenuWidget> {
|
|||
final itemCount = SettingActions.all.length;
|
||||
|
||||
moneroIcon = Image.asset('assets/images/monero_menu.png',
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.labelSmall!
|
||||
.decorationColor!);
|
||||
color: Theme.of(context).extension<CakeMenuTheme>()!.iconColor);
|
||||
bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.labelSmall!
|
||||
.decorationColor!);
|
||||
color: Theme.of(context).extension<CakeMenuTheme>()!.iconColor);
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Container(
|
||||
height: 60,
|
||||
width: 4,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(2)), color: PaletteDark.gray),
|
||||
)),
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Container(
|
||||
height: 60,
|
||||
width: 4,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(2)), color: PaletteDark.gray),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)),
|
||||
child: Container(
|
||||
color:
|
||||
Theme.of(context).textTheme!.bodyLarge!.decorationColor!,
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
itemBuilder: (_, index) {
|
||||
if (index == 0) {
|
||||
return Container(
|
||||
height: headerHeight,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
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),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_iconFor(type: widget.dashboardViewModel.type),
|
||||
SizedBox(width: 12),
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: widget.dashboardViewModel.subname.isNotEmpty
|
||||
? MainAxisAlignment.spaceBetween
|
||||
: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
widget.dashboardViewModel.name,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (widget.dashboardViewModel.subname.isNotEmpty)
|
||||
Observer(
|
||||
builder: (_) => Text(
|
||||
widget.dashboardViewModel.subname,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.labelSmall!
|
||||
.decorationColor!,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
))
|
||||
],
|
||||
child: ClipRRect(
|
||||
borderRadius:
|
||||
BorderRadius.only(topLeft: Radius.circular(24), bottomLeft: Radius.circular(24)),
|
||||
child: Container(
|
||||
color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor,
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
itemBuilder: (_, index) {
|
||||
if (index == 0) {
|
||||
return Container(
|
||||
height: headerHeight,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
Theme.of(context).extension<CakeMenuTheme>()!.headerFirstGradientColor,
|
||||
Theme.of(context).extension<CakeMenuTheme>()!.headerSecondGradientColor,
|
||||
], begin: Alignment.topLeft, end: Alignment.bottomRight),
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
left: 24, top: fromTopEdge, right: 24, bottom: fromBottomEdge),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_iconFor(type: widget.dashboardViewModel.type),
|
||||
SizedBox(width: 12),
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: widget.dashboardViewModel.subname.isNotEmpty
|
||||
? MainAxisAlignment.spaceBetween
|
||||
: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
widget.dashboardViewModel.name,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
))
|
||||
],
|
||||
if (widget.dashboardViewModel.subname.isNotEmpty)
|
||||
Observer(
|
||||
builder: (_) => Text(
|
||||
widget.dashboardViewModel.subname,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.extension<CakeMenuTheme>()!
|
||||
.subnameTextColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
index--;
|
||||
|
||||
final item = SettingActions.all[index];
|
||||
|
||||
final isLastTile = index == itemCount - 1;
|
||||
|
||||
return SettingActionButton(
|
||||
isLastTile: isLastTile,
|
||||
tileHeight: tileHeight,
|
||||
selectionActive: false,
|
||||
fromBottomEdge: fromBottomEdge,
|
||||
fromTopEdge: fromTopEdge,
|
||||
onTap: () => item.onTap.call(context),
|
||||
image: item.image,
|
||||
title: item.name.call(context),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, index) => Container(
|
||||
height: 1,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.bodySmall!
|
||||
.decorationColor!,
|
||||
),
|
||||
itemCount: itemCount + 1),
|
||||
)))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
index--;
|
||||
|
||||
final item = SettingActions.all[index];
|
||||
|
||||
final isLastTile = index == itemCount - 1;
|
||||
|
||||
return SettingActionButton(
|
||||
isLastTile: isLastTile,
|
||||
tileHeight: tileHeight,
|
||||
selectionActive: false,
|
||||
fromBottomEdge: fromBottomEdge,
|
||||
fromTopEdge: fromTopEdge,
|
||||
onTap: () => item.onTap.call(context),
|
||||
image: item.image,
|
||||
title: item.name.call(context),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (_, index) => Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor,
|
||||
),
|
||||
itemCount: itemCount + 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
|
||||
import 'package:cake_wallet/themes/extensions/order_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
|
||||
class OrderRow extends StatelessWidget {
|
||||
OrderRow({
|
||||
|
@ -20,7 +23,7 @@ class OrderRow extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final iconColor =
|
||||
Theme.of(context).primaryTextTheme!.displayLarge!.backgroundColor!;
|
||||
Theme.of(context).extension<OrderTheme>()!.iconColor;
|
||||
|
||||
final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor);
|
||||
|
||||
|
@ -48,14 +51,14 @@ class OrderRow extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
)),
|
||||
formattedAmount != null
|
||||
? Text(formattedAmount! + ' ' + to,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor
|
||||
))
|
||||
: Container()
|
||||
]),
|
||||
|
@ -66,10 +69,7 @@ class OrderRow extends StatelessWidget {
|
|||
Text(createdAtFormattedDate,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme!
|
||||
.labelSmall!
|
||||
.backgroundColor!))
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
|
||||
])
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/screens/ionia/widgets/rounded_checkbox.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
|
@ -10,22 +11,16 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
|
||||
class PresentReceiveOptionPicker extends StatelessWidget {
|
||||
PresentReceiveOptionPicker(
|
||||
{required this.receiveOptionViewModel, this.hasWhiteBackground = false});
|
||||
{required this.receiveOptionViewModel, required this.color});
|
||||
|
||||
final ReceiveOptionViewModel receiveOptionViewModel;
|
||||
final bool hasWhiteBackground;
|
||||
final Color color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final textIconTheme = hasWhiteBackground
|
||||
? Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayMedium!
|
||||
.backgroundColor!
|
||||
: Colors.white;
|
||||
final arrowBottom = Image.asset(
|
||||
'assets/images/arrow_bottom_purple_icon.png',
|
||||
color: textIconTheme,
|
||||
color: color,
|
||||
height: 6,
|
||||
);
|
||||
|
||||
|
@ -51,14 +46,14 @@ class PresentReceiveOptionPicker extends StatelessWidget {
|
|||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Lato',
|
||||
color: textIconTheme),
|
||||
color: color),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => Text(receiveOptionViewModel.selectedReceiveOption.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: textIconTheme)))
|
||||
color: color)))
|
||||
],
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
|
@ -113,10 +108,7 @@ class PresentReceiveOptionPicker extends StatelessWidget {
|
|||
Text(option.toString(),
|
||||
textAlign: TextAlign.left,
|
||||
style: textSmall(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
).copyWith(
|
||||
fontWeight:
|
||||
value == option ? FontWeight.w800 : FontWeight.w500,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/core/sync_status_title.dart';
|
||||
|
@ -32,7 +33,7 @@ class SyncIndicator extends StatelessWidget {
|
|||
child: Container(
|
||||
height: 30,
|
||||
width: syncIndicatorWidth,
|
||||
color: Theme.of(context).textTheme!.titleLarge!.decorationColor!,
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.notSyncedBackgroundColor,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
|
@ -44,7 +45,7 @@ class SyncIndicator extends StatelessWidget {
|
|||
child: Container(
|
||||
width: indicatorWidth,
|
||||
height: 30,
|
||||
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!,
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
|
||||
)
|
||||
)
|
||||
: Offstage(),
|
||||
|
@ -66,7 +67,7 @@ class SyncIndicator extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).textTheme!.titleLarge!.color!
|
||||
color: Theme.of(context).extension<SyncIndicatorTheme>()!.textColor
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
|
@ -26,7 +28,7 @@ class SyncIndicatorIcon extends StatelessWidget {
|
|||
if (boolMode) {
|
||||
indicatorColor = isSynced
|
||||
? PaletteDark.brightGreen
|
||||
: Theme.of(context).textTheme!.bodySmall!.color!;
|
||||
: Theme.of(context).extension<SyncIndicatorTheme>()!.notSyncedIconColor;
|
||||
} else {
|
||||
switch (value.toLowerCase()) {
|
||||
case waiting:
|
||||
|
@ -34,7 +36,7 @@ class SyncIndicatorIcon extends StatelessWidget {
|
|||
break;
|
||||
case actionRequired:
|
||||
indicatorColor =
|
||||
Theme.of(context).textTheme!.displayMedium!.decorationColor!;
|
||||
Theme.of(context).extension<ReceivePageTheme>()!.currentTileBackgroundColor;
|
||||
break;
|
||||
case created:
|
||||
indicatorColor = PaletteDark.brightGreen;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
|
||||
class TradeRow extends StatelessWidget {
|
||||
TradeRow({
|
||||
|
@ -43,14 +45,14 @@ class TradeRow extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!)),
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor)),
|
||||
formattedAmount != null
|
||||
? Text(formattedAmount! + ' ' + amountCrypto,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color:
|
||||
Theme.of(context).accentTextTheme!.displayMedium!.backgroundColor!))
|
||||
Theme.of(context).extension<DashboardPageTheme>()!.textColor))
|
||||
: Container()
|
||||
]),
|
||||
SizedBox(height: 5),
|
||||
|
@ -59,7 +61,7 @@ class TradeRow extends StatelessWidget {
|
|||
Text(createdAtFormattedDate!,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).textTheme!.labelSmall!.backgroundColor!))
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
|
||||
])
|
||||
],
|
||||
))
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
|
||||
class TransactionRow extends StatelessWidget {
|
||||
TransactionRow(
|
||||
|
@ -35,7 +38,7 @@ class TransactionRow extends StatelessWidget {
|
|||
width: 36,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).textTheme!.labelSmall!.decorationColor!
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.rowsColor
|
||||
),
|
||||
child: Image.asset(
|
||||
direction == TransactionDirection.incoming
|
||||
|
@ -54,14 +57,12 @@ class TransactionRow extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme!
|
||||
.displayMedium!.backgroundColor!)),
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor)),
|
||||
Text(formattedAmount,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme!
|
||||
.displayMedium!.backgroundColor!))
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor))
|
||||
]),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
|
@ -70,17 +71,11 @@ class TransactionRow extends StatelessWidget {
|
|||
Text(formattedDate,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme!
|
||||
.labelSmall!
|
||||
.backgroundColor!)),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor)),
|
||||
Text(formattedFiatAmount,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme!
|
||||
.labelSmall!
|
||||
.backgroundColor!))
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.dateSectionRowColor))
|
||||
])
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
|
||||
import 'package:cake_wallet/themes/extensions/placeholder_theme.dart';
|
||||
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
|
||||
|
@ -155,10 +156,7 @@ class TransactionsPage extends StatelessWidget {
|
|||
S.of(context).placeholder_transactions,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.labelSmall!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).extension<PlaceholderTheme>()!.color),
|
||||
),
|
||||
);
|
||||
}))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
@ -87,10 +89,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -107,10 +106,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -126,10 +122,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
))
|
||||
],
|
||||
),
|
||||
|
@ -146,10 +139,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -167,7 +157,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
changenowUrl,
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
color: Palette.blueCraiola,
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.normal,
|
||||
decoration: TextDecoration.underline),
|
||||
|
@ -193,7 +183,8 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context)
|
||||
.backgroundColor
|
||||
.colorScheme
|
||||
.background
|
||||
.withOpacity(0.0),
|
||||
Theme.of(context).colorScheme.background,
|
||||
],
|
||||
|
@ -232,10 +223,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.bodySmall!
|
||||
.color!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
|
||||
width: 1.0),
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8.0)),
|
||||
|
@ -253,10 +241,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -273,14 +258,8 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
|
|||
.popAndPushNamed(Routes.welcome)
|
||||
: null,
|
||||
text: 'Accept',
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.titleSmall!
|
||||
.decorationColor!,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.headlineSmall!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).extension<WalletListTheme>()!.createNewWalletButtonBackgroundColor,
|
||||
textColor: Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/core/auth_service.dart';
|
||||
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/extensions/send_page_theme.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';
|
||||
|
@ -78,7 +81,10 @@ class ExchangePage extends BasePage {
|
|||
String get title => S.current.exchange;
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.white;
|
||||
bool get gradientBackground => true;
|
||||
|
||||
@override
|
||||
bool get gradientAll => true;
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
@ -115,7 +121,7 @@ class ExchangePage extends BasePage {
|
|||
Widget? leading(BuildContext context) {
|
||||
final _backButton = Icon(
|
||||
Icons.arrow_back_ios,
|
||||
color: titleColor,
|
||||
color: titleColor(context),
|
||||
size: 16,
|
||||
);
|
||||
final _closeButton =
|
||||
|
@ -152,7 +158,7 @@ class ExchangePage extends BasePage {
|
|||
disableScroll: true,
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme.bodyLarge!.backgroundColor!,
|
||||
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
|
@ -205,8 +211,8 @@ class ExchangePage extends BasePage {
|
|||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme.displayLarge!
|
||||
.decorationColor!,
|
||||
.extension<ExchangePageTheme>()!
|
||||
.receiveAmountColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
),
|
||||
|
@ -244,7 +250,7 @@ class ExchangePage extends BasePage {
|
|||
}
|
||||
}
|
||||
},
|
||||
color: Theme.of(context).accentTextTheme.bodyLarge!.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isDisabled: exchangeViewModel.selectedProviders.isEmpty,
|
||||
isLoading: exchangeViewModel.tradeState is TradeIsCreating)),
|
||||
|
@ -624,8 +630,8 @@ class ExchangePage extends BasePage {
|
|||
},
|
||||
imageArrow: arrowBottomPurple,
|
||||
currencyButtonColor: Colors.transparent,
|
||||
addressButtonsColor: Theme.of(context).focusColor,
|
||||
borderColor: Theme.of(context).primaryTextTheme.bodyLarge!.color!,
|
||||
addressButtonsColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||
borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderTopPanelColor,
|
||||
currencyValueValidator: (value) {
|
||||
return !exchangeViewModel.isFixedRateMode
|
||||
? AmountValidator(
|
||||
|
@ -672,8 +678,8 @@ class ExchangePage extends BasePage {
|
|||
exchangeViewModel.changeReceiveCurrency(currency: currency),
|
||||
imageArrow: arrowBottomCakeGreen,
|
||||
currencyButtonColor: Colors.transparent,
|
||||
addressButtonsColor: Theme.of(context).focusColor,
|
||||
borderColor: Theme.of(context).primaryTextTheme.bodyLarge!.decorationColor!,
|
||||
addressButtonsColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||
borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
|
||||
currencyValueValidator: (value) {
|
||||
return exchangeViewModel.isFixedRateMode
|
||||
? AmountValidator(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
|
@ -29,10 +31,10 @@ class ExchangeTemplatePage extends BasePage {
|
|||
var _isReactionsSet = false;
|
||||
|
||||
@override
|
||||
String get title => S.current.exchange_new_template;
|
||||
bool get gradientAll => true;
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.white;
|
||||
String get title => S.current.exchange_new_template;
|
||||
|
||||
@override
|
||||
bool get extendBodyBehindAppBar => true;
|
||||
|
@ -73,10 +75,7 @@ class ExchangeTemplatePage extends BasePage {
|
|||
disableScroll: true,
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.backgroundColor!,
|
||||
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
|
@ -101,8 +100,8 @@ class ExchangeTemplatePage extends BasePage {
|
|||
),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).primaryTextTheme!.bodyMedium!.color!,
|
||||
Theme.of(context).primaryTextTheme!.bodyMedium!.decorationColor!,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.secondGradientBottomPanelColor,
|
||||
],
|
||||
stops: [0.35, 1.0],
|
||||
begin: Alignment.topLeft,
|
||||
|
@ -120,12 +119,8 @@ class ExchangeTemplatePage extends BasePage {
|
|||
),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context)
|
||||
.primaryTextTheme!.titleSmall!
|
||||
.color!,
|
||||
Theme.of(context)
|
||||
.primaryTextTheme!.titleSmall!
|
||||
.decorationColor!,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.firstGradientTopPanelColor,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.secondGradientTopPanelColor,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight),
|
||||
|
@ -157,10 +152,8 @@ class ExchangeTemplatePage extends BasePage {
|
|||
imageArrow: arrowBottomPurple,
|
||||
currencyButtonColor: Colors.transparent,
|
||||
addressButtonsColor:
|
||||
Theme.of(context).focusColor,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme!.bodyLarge!
|
||||
.color!,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.textFieldButtonColor,
|
||||
borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
|
||||
currencyValueValidator: AmountValidator(
|
||||
currency: exchangeViewModel.depositCurrency),
|
||||
//addressTextFieldValidator: AddressValidator(
|
||||
|
@ -197,10 +190,8 @@ class ExchangeTemplatePage extends BasePage {
|
|||
imageArrow: arrowBottomCakeGreen,
|
||||
currencyButtonColor: Colors.transparent,
|
||||
addressButtonsColor:
|
||||
Theme.of(context).focusColor,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme!.bodyLarge!
|
||||
.decorationColor!,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.textFieldButtonColor,
|
||||
borderColor: Theme.of(context).extension<ExchangePageTheme>()!.textFieldBorderBottomPanelColor,
|
||||
currencyValueValidator: AmountValidator(
|
||||
currency: exchangeViewModel.receiveCurrency),
|
||||
//addressTextFieldValidator: AddressValidator(
|
||||
|
@ -226,9 +217,7 @@ class ExchangeTemplatePage extends BasePage {
|
|||
description,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!.displayLarge!
|
||||
.decorationColor!,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.receiveAmountColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
),
|
||||
|
@ -256,7 +245,7 @@ class ExchangeTemplatePage extends BasePage {
|
|||
}
|
||||
},
|
||||
text: S.of(context).save,
|
||||
color: Colors.green,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white),
|
||||
]),
|
||||
))
|
||||
|
@ -444,4 +433,4 @@ class ExchangeTemplatePage extends BasePage {
|
|||
key.currentState!.addressController.text = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_scrollbar_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
|
@ -20,10 +22,7 @@ class PickerItemWidget extends StatelessWidget {
|
|||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.titleLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).dialogTheme.backgroundColor,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
|
||||
child: Row(
|
||||
|
@ -44,10 +43,7 @@ class PickerItemWidget extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
color: isSelected
|
||||
? Palette.blueCraiola
|
||||
: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!,
|
||||
: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
fontSize: isSelected ? 16 : 14.0,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w600,
|
||||
|
@ -65,19 +61,13 @@ class PickerItemWidget extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 7.0,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context)
|
||||
.textTheme!
|
||||
.bodyMedium!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeScrollbarTheme>()!.thumbColor),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6.0),
|
||||
//border: Border.all(color: ),
|
||||
color: Theme.of(context)
|
||||
.textTheme!
|
||||
.bodyMedium!
|
||||
.decorationColor!,
|
||||
color: Theme.of(context).extension<CakeScrollbarTheme>()!.trackColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -86,10 +76,7 @@ class PickerItemWidget extends StatelessWidget {
|
|||
),
|
||||
if (isSelected)
|
||||
Icon(Icons.check_circle,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!)
|
||||
color: Theme.of(context).primaryColor)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
|
||||
import 'package:cw_core/currency.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'currency_picker_item_widget.dart';
|
||||
|
@ -20,10 +21,7 @@ class CurrencyPickerWidget extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.titleLarge!
|
||||
.backgroundColor!,
|
||||
color: Theme.of(context).extension<PickerTheme>()!.dividerColor,
|
||||
child: Scrollbar(
|
||||
controller: _scrollController,
|
||||
child: GridView.builder(
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:cake_wallet/entities/contact_base.dart';
|
||||
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/utils/payment_request.dart';
|
||||
|
@ -12,6 +14,7 @@ import 'package:cw_core/crypto_currency.dart';
|
|||
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||
|
||||
class ExchangeCard extends StatefulWidget {
|
||||
ExchangeCard(
|
||||
|
@ -160,7 +163,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
final copyImage = Image.asset('assets/images/copy_content.png',
|
||||
height: 16,
|
||||
width: 16,
|
||||
color: Theme.of(context).primaryTextTheme!.displaySmall!.color!);
|
||||
color: Theme.of(context).extension<SendPageTheme>()!.estimatedFeeColor);
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
|
@ -175,7 +178,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).textTheme!.headlineSmall!.color!),
|
||||
color: Theme.of(context).extension<QRCodeTheme>()!.qrCodeColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -211,10 +214,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.addressButtonsColor ??
|
||||
Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.headlineMedium!
|
||||
.color!,
|
||||
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(6))),
|
||||
child: Center(
|
||||
|
@ -224,10 +224,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.headlineMedium!
|
||||
.decorationColor!)),
|
||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor)),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -268,10 +265,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayLarge!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
|
||||
validator: _isAmountEditable
|
||||
? widget.currencyValueValidator
|
||||
: null),
|
||||
|
@ -282,10 +276,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
height: 32,
|
||||
width: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.headlineMedium!
|
||||
.color!,
|
||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(6))),
|
||||
child: InkWell(
|
||||
|
@ -296,10 +287,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.headlineMedium!
|
||||
.decorationColor!)),
|
||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor)),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -310,10 +298,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
)),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.headlineSmall!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Container(
|
||||
|
@ -329,10 +314,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayLarge!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
|
||||
)
|
||||
: Offstage(),
|
||||
_min != null ? SizedBox(width: 10) : Offstage(),
|
||||
|
@ -344,10 +326,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayLarge!
|
||||
.decorationColor!))
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor))
|
||||
: Offstage(),
|
||||
])),
|
||||
),
|
||||
|
@ -359,10 +338,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayLarge!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
|
||||
))
|
||||
: Offstage(),
|
||||
_isAddressEditable
|
||||
|
@ -400,10 +376,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayLarge!
|
||||
.decorationColor!),
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor),
|
||||
buttonColor: widget.addressButtonsColor,
|
||||
validator: widget.addressTextFieldValidator,
|
||||
onPushPasteButton: widget.onPushPasteButton,
|
||||
|
@ -472,10 +445,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
6))),
|
||||
child: Image.asset(
|
||||
'assets/images/open_book.png',
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.headlineMedium!
|
||||
.decorationColor!,
|
||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
|
||||
)),
|
||||
)),
|
||||
),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MobileExchangeCardsSection extends StatelessWidget {
|
||||
|
@ -21,8 +22,8 @@ class MobileExchangeCardsSection extends StatelessWidget {
|
|||
),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).primaryTextTheme!.bodyMedium!.color!,
|
||||
Theme.of(context).primaryTextTheme!.bodyMedium!.decorationColor!,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.secondGradientBottomPanelColor,
|
||||
],
|
||||
stops: [0.35, 1.0],
|
||||
begin: Alignment.topLeft,
|
||||
|
@ -37,11 +38,8 @@ class MobileExchangeCardsSection extends StatelessWidget {
|
|||
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context).primaryTextTheme!.titleSmall!.color!,
|
||||
Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleSmall!
|
||||
.decorationColor!,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.firstGradientTopPanelColor,
|
||||
Theme.of(context).extension<ExchangePageTheme>()!.secondGradientTopPanelColor,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
|
||||
import 'package:cake_wallet/src/widgets/check_box_picker.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -49,10 +50,7 @@ class PresentProviderPicker extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.textTheme!
|
||||
.headlineSmall!
|
||||
.color!)))
|
||||
color: Theme.of(context).extension<QRCodeTheme>()!.qrCodeColor)))
|
||||
],
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/store/dashboard/trades_store.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
@ -9,6 +11,7 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/exchange/trade.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
|
||||
class ExchangeConfirmPage extends BasePage {
|
||||
ExchangeConfirmPage({required this.tradesStore}) : trade = tradesStore.trade!;
|
||||
|
@ -36,10 +39,7 @@ class ExchangeConfirmPage extends BasePage {
|
|||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
)),
|
||||
Container(
|
||||
|
@ -48,14 +48,8 @@ class ExchangeConfirmPage extends BasePage {
|
|||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
border: Border.all(
|
||||
width: 1,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodySmall!
|
||||
.color!),
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).cardColor),
|
||||
color: Theme.of(context).dialogTheme.backgroundColor),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
|
@ -70,10 +64,7 @@ class ExchangeConfirmPage extends BasePage {
|
|||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.labelSmall!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
|
||||
),
|
||||
Text(
|
||||
trade.id,
|
||||
|
@ -82,10 +73,7 @@ class ExchangeConfirmPage extends BasePage {
|
|||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -100,14 +88,8 @@ class ExchangeConfirmPage extends BasePage {
|
|||
context, S.of(context).copied_to_clipboard);
|
||||
},
|
||||
text: S.of(context).copy_id,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodySmall!
|
||||
.backgroundColor!,
|
||||
textColor: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.buttonBackgroundColor,
|
||||
textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -136,10 +118,7 @@ class ExchangeConfirmPage extends BasePage {
|
|||
onPressed: () => Navigator.of(context)
|
||||
.pushReplacementNamed(Routes.exchangeTrade),
|
||||
text: S.of(context).saved_the_trade_id,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white)
|
||||
],
|
||||
),
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/utils/request_review_handler.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
@ -20,6 +22,7 @@ import 'package:cake_wallet/src/screens/exchange_trade/widgets/timer_widget.dart
|
|||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
|
||||
void showInformation(
|
||||
ExchangeTradeViewModel exchangeTradeViewModel, BuildContext context) {
|
||||
|
@ -51,7 +54,7 @@ class ExchangeTradePage extends BasePage {
|
|||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final questionImage = Image.asset('assets/images/question_mark.png',
|
||||
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!);
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor);
|
||||
|
||||
return SizedBox(
|
||||
height: 20.0,
|
||||
|
@ -111,7 +114,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
final copyImage = Image.asset('assets/images/copy_content.png',
|
||||
height: 16,
|
||||
width: 16,
|
||||
color: Theme.of(context).primaryTextTheme!.labelSmall!.color!);
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor);
|
||||
|
||||
_setEffects();
|
||||
|
||||
|
@ -133,17 +136,11 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.labelSmall!
|
||||
.color!),
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor),
|
||||
),
|
||||
if (trade.expiredAt != null)
|
||||
TimerWidget(trade.expiredAt!,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!)
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor)
|
||||
])
|
||||
: Offstage(),
|
||||
Padding(
|
||||
|
@ -160,10 +157,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 3,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.titleSmall!
|
||||
.color!
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.qrCodeColor
|
||||
)
|
||||
),
|
||||
child: QrImage(data: trade.inputAddress ?? fetchingLabel),
|
||||
|
@ -179,10 +173,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
itemCount: widget.exchangeTradeViewModel.items.length,
|
||||
separatorBuilder: (context, index) => Container(
|
||||
height: 1,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.titleSmall!
|
||||
.backgroundColor!,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.dividerCodeColor,
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final item = widget.exchangeTradeViewModel.items[index];
|
||||
|
@ -228,10 +219,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
onPressed: () =>
|
||||
widget.exchangeTradeViewModel.confirmSending(),
|
||||
text: S.of(context).confirm,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white)
|
||||
: Offstage();
|
||||
})),
|
||||
|
@ -321,7 +309,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
return Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
color: Theme.of(popupContext).backgroundColor,
|
||||
color: Theme.of(popupContext).colorScheme.background,
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
'assets/images/birthday_cake.png'),
|
||||
|
@ -341,10 +329,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(popupContext)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color,
|
||||
color: Theme.of(popupContext).extension<CakeTextTheme>()!.titleColor,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
|
@ -360,10 +345,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
RequestReviewHandler.requestReview();
|
||||
},
|
||||
text: S.of(popupContext).got_it,
|
||||
color: Theme.of(popupContext)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(popupContext).primaryColor,
|
||||
textColor: Colors.white))
|
||||
],
|
||||
);
|
||||
|
@ -372,7 +354,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
return Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
color: Theme.of(popupContext).backgroundColor,
|
||||
color: Theme.of(popupContext).colorScheme.background,
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
'assets/images/birthday_cake.png'),
|
||||
|
@ -384,7 +366,8 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(popupContext)
|
||||
.backgroundColor
|
||||
.colorScheme
|
||||
.background
|
||||
.withOpacity(0.25)),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
|
@ -395,10 +378,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(popupContext)
|
||||
.primaryTextTheme!
|
||||
.titleLarge!
|
||||
.color!,
|
||||
color: Theme.of(popupContext).extension<CakeTextTheme>()!.titleColor,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/info_theme.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_background.dart';
|
||||
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
|
||||
|
||||
class InformationPage extends StatelessWidget {
|
||||
InformationPage({required this.information});
|
||||
|
@ -21,7 +25,7 @@ class InformationPage extends StatelessWidget {
|
|||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
color: Theme.of(context).textTheme!.bodyLarge!.decorationColor!
|
||||
color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
@ -36,7 +40,7 @@ class InformationPage extends StatelessWidget {
|
|||
fontWeight: FontWeight.normal,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
color: Theme.of(context).accentTextTheme!.bodySmall!.decorationColor!
|
||||
color: Theme.of(context).extension<InfoTheme>()!.textColor
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -45,8 +49,8 @@ class InformationPage extends StatelessWidget {
|
|||
child: PrimaryButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
text: S.of(context).got_it,
|
||||
color: Theme.of(context).accentTextTheme!.bodySmall!.backgroundColor!,
|
||||
textColor: Theme.of(context).primaryTextTheme!.titleLarge!.color!
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.buttonBackgroundColor,
|
||||
textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor
|
||||
),
|
||||
)
|
||||
],
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
|
@ -26,12 +27,12 @@ class FAQItemState extends State<FAQItem> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final addIcon = Icon(Icons.add,
|
||||
color: Theme.of(context).primaryTextTheme!.titleLarge!.color!);
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor);
|
||||
final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola);
|
||||
final icon = isActive ? removeIcon : addIcon;
|
||||
final color = isActive
|
||||
? Palette.blueCraiola
|
||||
: Theme.of(context).primaryTextTheme!.titleLarge!.color!;
|
||||
: Theme.of(context).extension<CakeTextTheme>()!.titleColor;
|
||||
|
||||
return ListTileTheme(
|
||||
contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6),
|
||||
|
@ -54,7 +55,7 @@ class FAQItemState extends State<FAQItem> {
|
|||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color:
|
||||
Theme.of(context).primaryTextTheme!.titleLarge!.color!),
|
||||
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
|
||||
),
|
||||
))
|
||||
])
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/core/email_validator.dart';
|
||||
import 'package:cake_wallet/ionia/ionia_create_state.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
|
@ -40,10 +41,7 @@ class IoniaCreateAccountPage extends BasePage {
|
|||
return Text(
|
||||
S.current.sign_up,
|
||||
style: textMediumSemiBold(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.displayLarge!
|
||||
.backgroundColor!,
|
||||
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -84,10 +82,7 @@ class IoniaCreateAccountPage extends BasePage {
|
|||
onPressed: _createAccount,
|
||||
isLoading:
|
||||
_authViewModel.createUserState is IoniaCreateStateLoading,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
|
@ -107,10 +102,7 @@ class IoniaCreateAccountPage extends BasePage {
|
|||
TextSpan(
|
||||
text: S.of(context).settings_terms_and_conditions,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
|
@ -122,10 +114,7 @@ class IoniaCreateAccountPage extends BasePage {
|
|||
TextSpan(
|
||||
text: S.of(context).privacy_policy,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme!
|
||||
.bodyLarge!
|
||||
.color!,
|
||||
color: Theme.of(context).primaryColor,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue