mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-18 08:34:31 +00:00
Merge remote-tracking branch 'origin/staging' into tor
This commit is contained in:
commit
174e9b29a6
80 changed files with 3675 additions and 1217 deletions
Binary file not shown.
Binary file not shown.
|
@ -41,7 +41,6 @@ class DB {
|
||||||
String boxNameUsedSerialsCache({required Coin coin}) =>
|
String boxNameUsedSerialsCache({required Coin coin}) =>
|
||||||
"${coin.name}_usedSerialsCache";
|
"${coin.name}_usedSerialsCache";
|
||||||
|
|
||||||
Box<dynamic>? _boxAddressBook;
|
|
||||||
Box<String>? _boxDebugInfo;
|
Box<String>? _boxDebugInfo;
|
||||||
Box<NodeModel>? _boxNodeModels;
|
Box<NodeModel>? _boxNodeModels;
|
||||||
Box<NodeModel>? _boxPrimaryNodes;
|
Box<NodeModel>? _boxPrimaryNodes;
|
||||||
|
@ -100,7 +99,6 @@ class DB {
|
||||||
_boxPrefs = await Hive.openBox<dynamic>(boxNamePrefs);
|
_boxPrefs = await Hive.openBox<dynamic>(boxNamePrefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
_boxAddressBook = await Hive.openBox<dynamic>(boxNameAddressBook);
|
|
||||||
_boxDebugInfo = await Hive.openBox<String>(boxNameDebugInfo);
|
_boxDebugInfo = await Hive.openBox<String>(boxNameDebugInfo);
|
||||||
|
|
||||||
if (Hive.isBoxOpen(boxNameNodeModels)) {
|
if (Hive.isBoxOpen(boxNameNodeModels)) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter_native_splash/cli_commands.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/exceptions/main_db/main_db_exception.dart';
|
import 'package:stackwallet/exceptions/main_db/main_db_exception.dart';
|
||||||
import 'package:stackwallet/models/isar/models/block_explorer.dart';
|
import 'package:stackwallet/models/isar/models/block_explorer.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/isar/stack_theme.dart';
|
import 'package:stackwallet/models/isar/stack_theme.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
|
@ -37,6 +38,7 @@ class MainDB {
|
||||||
EthContractSchema,
|
EthContractSchema,
|
||||||
TransactionBlockExplorerSchema,
|
TransactionBlockExplorerSchema,
|
||||||
StackThemeSchema,
|
StackThemeSchema,
|
||||||
|
ContactEntrySchema,
|
||||||
],
|
],
|
||||||
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
||||||
// inspector: kDebugMode,
|
// inspector: kDebugMode,
|
||||||
|
@ -47,6 +49,45 @@ class MainDB {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// contact entries
|
||||||
|
List<ContactEntry> getContactEntries(){
|
||||||
|
return isar.contactEntrys.where().findAllSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> deleteContactEntry({required String id}) {
|
||||||
|
try {
|
||||||
|
return isar.writeTxn(() async {
|
||||||
|
await isar.contactEntrys.deleteByCustomId(id);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw MainDBException("failed deleteContactEntry: $id", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isContactEntryExists({required String id}) async {
|
||||||
|
return isar.contactEntrys
|
||||||
|
.where()
|
||||||
|
.customIdEqualTo(id)
|
||||||
|
.count()
|
||||||
|
.then((value) => value > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ContactEntry? getContactEntry({required String id}) {
|
||||||
|
return isar.contactEntrys.where().customIdEqualTo(id).findFirstSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> putContactEntry({required ContactEntry contactEntry}) async {
|
||||||
|
try {
|
||||||
|
return await isar.writeTxn(() async {
|
||||||
|
await isar.contactEntrys.put(contactEntry);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw MainDBException("failed putContactEntry: $contactEntry", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// tx block explorers
|
// tx block explorers
|
||||||
TransactionBlockExplorer? getTransactionBlockExplorer({required Coin coin}) {
|
TransactionBlockExplorer? getTransactionBlockExplorer({required Coin coin}) {
|
||||||
return isar.transactionBlockExplorers
|
return isar.transactionBlockExplorers
|
||||||
|
|
|
@ -162,7 +162,7 @@ void main() async {
|
||||||
int dbVersion = DB.instance.get<dynamic>(
|
int dbVersion = DB.instance.get<dynamic>(
|
||||||
boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
|
boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
|
||||||
0;
|
0;
|
||||||
if (dbVersion < Constants.currentHiveDbVersion) {
|
if (dbVersion < Constants.currentDataVersion) {
|
||||||
try {
|
try {
|
||||||
await DbVersionMigrator().migrate(
|
await DbVersionMigrator().migrate(
|
||||||
dbVersion,
|
dbVersion,
|
||||||
|
@ -178,9 +178,6 @@ void main() async {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add Themes directory - TODO
|
|
||||||
// await StackFileSystem.applicationThemesDirectory();
|
|
||||||
|
|
||||||
monero.onStartup();
|
monero.onStartup();
|
||||||
wownero.onStartup();
|
wownero.onStartup();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
import 'package:stackwallet/models/contact_address_entry.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
@Deprecated("Use lib/models/isar/models/contact_entry.dart instead")
|
||||||
class Contact {
|
class Contact {
|
||||||
final String? emojiChar;
|
final String? emojiChar;
|
||||||
final String name;
|
final String name;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
|
@Deprecated("Use lib/models/isar/models/contact_entry.dart instead")
|
||||||
class ContactAddressEntry {
|
class ContactAddressEntry {
|
||||||
final Coin coin;
|
final Coin coin;
|
||||||
final String address;
|
final String address;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/utilities/address_utils.dart';
|
import 'package:stackwallet/utilities/address_utils.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class AddressEntryData extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isValidAddress {
|
bool get isValidAddress {
|
||||||
if ( coin == null) {
|
if (coin == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (_address == null) {
|
if (_address == null) {
|
||||||
|
@ -67,8 +67,11 @@ class AddressEntryData extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactAddressEntry buildAddressEntry() {
|
ContactAddressEntry buildAddressEntry() {
|
||||||
return ContactAddressEntry(
|
return ContactAddressEntry()
|
||||||
coin: coin!, address: address!, label: addressLabel!);
|
..coinName = coin!.name
|
||||||
|
..address = address!
|
||||||
|
..other = null
|
||||||
|
..label = addressLabel!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
108
lib/models/isar/models/contact_entry.dart
Normal file
108
lib/models/isar/models/contact_entry.dart
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
|
part 'contact_entry.g.dart';
|
||||||
|
|
||||||
|
@collection
|
||||||
|
class ContactEntry {
|
||||||
|
ContactEntry({
|
||||||
|
this.emojiChar,
|
||||||
|
required this.name,
|
||||||
|
required this.addresses,
|
||||||
|
required this.isFavorite,
|
||||||
|
required this.customId,
|
||||||
|
});
|
||||||
|
|
||||||
|
Id id = Isar.autoIncrement;
|
||||||
|
|
||||||
|
late final String? emojiChar;
|
||||||
|
late final String name;
|
||||||
|
late final List<ContactAddressEntry> addresses;
|
||||||
|
late final bool isFavorite;
|
||||||
|
|
||||||
|
@Index(unique: true, replace: true)
|
||||||
|
late final String customId;
|
||||||
|
|
||||||
|
ContactEntry copyWith({
|
||||||
|
bool shouldCopyEmojiWithNull = false,
|
||||||
|
String? emojiChar,
|
||||||
|
String? name,
|
||||||
|
List<ContactAddressEntry>? addresses,
|
||||||
|
bool? isFavorite,
|
||||||
|
}) {
|
||||||
|
List<ContactAddressEntry> _addresses = [];
|
||||||
|
if (addresses == null) {
|
||||||
|
for (var e in this.addresses) {
|
||||||
|
_addresses.add(e.copyWith());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var e in addresses) {
|
||||||
|
_addresses.add(e.copyWith());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String? newEmoji;
|
||||||
|
if (shouldCopyEmojiWithNull) {
|
||||||
|
newEmoji = emojiChar;
|
||||||
|
} else {
|
||||||
|
newEmoji = emojiChar ?? this.emojiChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ContactEntry(
|
||||||
|
emojiChar: newEmoji,
|
||||||
|
name: name ?? this.name,
|
||||||
|
addresses: _addresses,
|
||||||
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
|
customId: customId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"emoji": emojiChar,
|
||||||
|
"name": name,
|
||||||
|
"addresses": addresses.map((e) => e.toMap()).toList(),
|
||||||
|
"id": customId,
|
||||||
|
"isFavorite": isFavorite,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@embedded
|
||||||
|
class ContactAddressEntry {
|
||||||
|
late final String coinName;
|
||||||
|
late final String address;
|
||||||
|
late final String label;
|
||||||
|
late final String? other;
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
Coin get coin => Coin.values.byName(coinName);
|
||||||
|
|
||||||
|
ContactAddressEntry();
|
||||||
|
|
||||||
|
ContactAddressEntry copyWith({
|
||||||
|
Coin? coin,
|
||||||
|
String? address,
|
||||||
|
String? label,
|
||||||
|
String? other,
|
||||||
|
}) {
|
||||||
|
return ContactAddressEntry()
|
||||||
|
..coinName = coin?.name ?? coinName
|
||||||
|
..address = address ?? this.address
|
||||||
|
..label = label ?? this.label
|
||||||
|
..other = other ?? this.other;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> toMap() {
|
||||||
|
return {
|
||||||
|
"label": label,
|
||||||
|
"address": address,
|
||||||
|
"coin": coin.name,
|
||||||
|
"other": other ?? "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return "AddressBookEntry: ${toMap()}";
|
||||||
|
}
|
||||||
|
}
|
1808
lib/models/isar/models/contact_entry.g.dart
Normal file
1808
lib/models/isar/models/contact_entry.g.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -794,6 +794,15 @@ class StackTheme {
|
||||||
Color? _bottomNavIconIcon;
|
Color? _bottomNavIconIcon;
|
||||||
final int bottomNavIconIconInt;
|
final int bottomNavIconIconInt;
|
||||||
|
|
||||||
|
// ==== bottomNavIconIcon highlighted =====================================================
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
Color get bottomNavIconIconHighlighted =>
|
||||||
|
_bottomNavIconIconHighlighted ??= Color(bottomNavIconIconHighlightedInt);
|
||||||
|
@ignore
|
||||||
|
Color? _bottomNavIconIconHighlighted;
|
||||||
|
final int bottomNavIconIconHighlightedInt;
|
||||||
|
|
||||||
// ==== topNavIconPrimary =====================================================
|
// ==== topNavIconPrimary =====================================================
|
||||||
|
|
||||||
@ignore
|
@ignore
|
||||||
|
@ -1556,6 +1565,7 @@ class StackTheme {
|
||||||
required this.snackBarTextInfoInt,
|
required this.snackBarTextInfoInt,
|
||||||
required this.bottomNavIconBackInt,
|
required this.bottomNavIconBackInt,
|
||||||
required this.bottomNavIconIconInt,
|
required this.bottomNavIconIconInt,
|
||||||
|
required this.bottomNavIconIconHighlightedInt,
|
||||||
required this.topNavIconPrimaryInt,
|
required this.topNavIconPrimaryInt,
|
||||||
required this.topNavIconGreenInt,
|
required this.topNavIconGreenInt,
|
||||||
required this.topNavIconYellowInt,
|
required this.topNavIconYellowInt,
|
||||||
|
@ -1795,6 +1805,8 @@ class StackTheme {
|
||||||
parseColor(json["colors"]["bottom_nav_icon_back"] as String),
|
parseColor(json["colors"]["bottom_nav_icon_back"] as String),
|
||||||
bottomNavIconIconInt:
|
bottomNavIconIconInt:
|
||||||
parseColor(json["colors"]["bottom_nav_icon_icon"] as String),
|
parseColor(json["colors"]["bottom_nav_icon_icon"] as String),
|
||||||
|
bottomNavIconIconHighlightedInt: parseColor(
|
||||||
|
json["colors"]["bottom_nav_icon_icon_highlighted"] as String),
|
||||||
topNavIconPrimaryInt:
|
topNavIconPrimaryInt:
|
||||||
parseColor(json["colors"]["top_nav_icon_primary"] as String),
|
parseColor(json["colors"]["top_nav_icon_primary"] as String),
|
||||||
topNavIconGreenInt:
|
topNavIconGreenInt:
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,14 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/models/isar/stack_theme.dart';
|
||||||
import 'package:stackwallet/models/notification_model.dart';
|
import 'package:stackwallet/models/notification_model.dart';
|
||||||
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/themes/theme_providers.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/format.dart';
|
import 'package:stackwallet/utilities/format.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
@ -9,7 +16,7 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_container.dart';
|
import 'package:stackwallet/widgets/rounded_container.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
class NotificationCard extends StatelessWidget {
|
class NotificationCard extends ConsumerWidget {
|
||||||
const NotificationCard({
|
const NotificationCard({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.notification,
|
required this.notification,
|
||||||
|
@ -25,8 +32,17 @@ class NotificationCard extends StatelessWidget {
|
||||||
static const double mobileIconSize = 24;
|
static const double mobileIconSize = 24;
|
||||||
static const double desktopIconSize = 30;
|
static const double desktopIconSize = 30;
|
||||||
|
|
||||||
|
String coinIconPath(ThemeAssets assets, WidgetRef ref) {
|
||||||
|
try {
|
||||||
|
final coin = coinFromPrettyName(notification.coinName);
|
||||||
|
return ref.read(coinIconProvider(coin));
|
||||||
|
} catch (_) {
|
||||||
|
return notification.iconAssetName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final isDesktop = Util.isDesktop;
|
final isDesktop = Util.isDesktop;
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
|
@ -41,8 +57,14 @@ class NotificationCard extends StatelessWidget {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
notification.changeNowId == null
|
notification.changeNowId == null
|
||||||
? SvgPicture.asset(
|
? SvgPicture.file(
|
||||||
notification.iconAssetName,
|
File(
|
||||||
|
coinIconPath(
|
||||||
|
ref.watch(
|
||||||
|
themeProvider.select((value) => value.assets),
|
||||||
|
),
|
||||||
|
ref),
|
||||||
|
),
|
||||||
width: isDesktop ? desktopIconSize : mobileIconSize,
|
width: isDesktop ? desktopIconSize : mobileIconSize,
|
||||||
height: isDesktop ? desktopIconSize : mobileIconSize,
|
height: isDesktop ? desktopIconSize : mobileIconSize,
|
||||||
)
|
)
|
||||||
|
@ -53,8 +75,14 @@ class NotificationCard extends StatelessWidget {
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
borderRadius: BorderRadius.circular(24),
|
borderRadius: BorderRadius.circular(24),
|
||||||
),
|
),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
notification.iconAssetName,
|
File(
|
||||||
|
coinIconPath(
|
||||||
|
ref.watch(
|
||||||
|
themeProvider.select((value) => value.assets),
|
||||||
|
),
|
||||||
|
ref),
|
||||||
|
),
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.accentColorDark,
|
.accentColorDark,
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
|
@ -73,19 +72,18 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
|
||||||
final managers = ref.read(walletsChangeNotifierProvider).managers;
|
final managers = ref.read(walletsChangeNotifierProvider).managers;
|
||||||
for (final manager in managers) {
|
for (final manager in managers) {
|
||||||
addresses.add(
|
addresses.add(
|
||||||
ContactAddressEntry(
|
ContactAddressEntry()
|
||||||
coin: manager.coin,
|
..coinName = manager.coin.name
|
||||||
address: await manager.currentReceivingAddress,
|
..address = await manager.currentReceivingAddress
|
||||||
label: "Current Receiving",
|
..label = "Current Receiving"
|
||||||
other: manager.walletName,
|
..other = manager.walletName,
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final self = Contact(
|
final self = ContactEntry(
|
||||||
name: "My Stack",
|
name: "My Stack",
|
||||||
addresses: addresses,
|
addresses: addresses,
|
||||||
isFavorite: true,
|
isFavorite: true,
|
||||||
id: "default",
|
customId: "default",
|
||||||
);
|
);
|
||||||
await ref.read(addressBookServiceProvider).editContact(self);
|
await ref.read(addressBookServiceProvider).editContact(self);
|
||||||
});
|
});
|
||||||
|
@ -306,8 +304,8 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
|
||||||
.where((element) => element.isFavorite)
|
.where((element) => element.isFavorite)
|
||||||
.map(
|
.map(
|
||||||
(e) => AddressBookCard(
|
(e) => AddressBookCard(
|
||||||
key: Key("favContactCard_${e.id}_key"),
|
key: Key("favContactCard_${e.customId}_key"),
|
||||||
contactId: e.id,
|
contactId: e.customId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -352,8 +350,9 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
|
||||||
.matches(widget.filterTerm ?? _searchTerm, e))
|
.matches(widget.filterTerm ?? _searchTerm, e))
|
||||||
.map(
|
.map(
|
||||||
(e) => AddressBookCard(
|
(e) => AddressBookCard(
|
||||||
key: Key("desktopContactCard_${e.id}_key"),
|
key:
|
||||||
contactId: e.id,
|
Key("desktopContactCard_${e.customId}_key"),
|
||||||
|
contactId: e.customId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,8 +2,7 @@ import 'package:emojis/emoji.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/new_contact_address_entry_form.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/new_contact_address_entry_form.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
||||||
|
@ -28,6 +27,7 @@ import 'package:stackwallet/widgets/emoji_select_sheet.dart';
|
||||||
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
|
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
|
||||||
import 'package:stackwallet/widgets/stack_text_field.dart';
|
import 'package:stackwallet/widgets/stack_text_field.dart';
|
||||||
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
import 'package:stackwallet/widgets/textfield_icon_button.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class AddAddressBookEntryView extends ConsumerStatefulWidget {
|
class AddAddressBookEntryView extends ConsumerStatefulWidget {
|
||||||
const AddAddressBookEntryView({
|
const AddAddressBookEntryView({
|
||||||
|
@ -688,11 +688,12 @@ class _AddAddressBookEntryViewState
|
||||||
forms[i].id))
|
forms[i].id))
|
||||||
.buildAddressEntry());
|
.buildAddressEntry());
|
||||||
}
|
}
|
||||||
Contact contact = Contact(
|
ContactEntry contact = ContactEntry(
|
||||||
emojiChar: _selectedEmoji?.char,
|
emojiChar: _selectedEmoji?.char,
|
||||||
name: nameController.text,
|
name: nameController.text,
|
||||||
addresses: entries,
|
addresses: entries,
|
||||||
isFavorite: _isFavorite,
|
isFavorite: _isFavorite,
|
||||||
|
customId: const Uuid().v1(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (await ref
|
if (await ref
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/new_contact_address_entry_form.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/new_contact_address_entry_form.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
||||||
|
@ -208,7 +207,7 @@ class _AddNewContactAddressViewState
|
||||||
.read(addressEntryDataProvider(0))
|
.read(addressEntryDataProvider(0))
|
||||||
.buildAddressEntry());
|
.buildAddressEntry());
|
||||||
|
|
||||||
Contact editedContact =
|
ContactEntry editedContact =
|
||||||
contact.copyWith(addresses: entries);
|
contact.copyWith(addresses: entries);
|
||||||
|
|
||||||
if (await ref
|
if (await ref
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_image_provider.dart';
|
import 'package:stackwallet/themes/coin_image_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
@ -87,8 +89,10 @@ class CoinSelectSheet extends StatelessWidget {
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinImageProvider(coin)),
|
File(
|
||||||
|
ref.watch(coinImageProvider(coin)),
|
||||||
|
),
|
||||||
height: 20,
|
height: 20,
|
||||||
width: 20,
|
width: 20,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
@ -13,8 +15,8 @@ import 'package:stackwallet/providers/global/address_book_service_provider.dart'
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/manager.dart';
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
@ -197,7 +199,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ref
|
ref
|
||||||
.read(addressBookServiceProvider)
|
.read(addressBookServiceProvider)
|
||||||
.removeContact(_contact.id);
|
.removeContact(_contact.customId);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
showFloatingFlushBar(
|
showFloatingFlushBar(
|
||||||
|
@ -334,8 +336,10 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
|
||||||
padding: const EdgeInsets.all(12),
|
padding: const EdgeInsets.all(12),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(e.coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(e.coin)),
|
||||||
|
),
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
@ -9,8 +11,8 @@ import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.
|
||||||
import 'package:stackwallet/pages/send_view/send_view.dart';
|
import 'package:stackwallet/pages/send_view/send_view.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/themes/theme_providers.dart';
|
import 'package:stackwallet/themes/theme_providers.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
||||||
|
@ -110,11 +112,13 @@ class ContactPopUp extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
child: contact.id == "default"
|
child: contact.id == "default"
|
||||||
? Center(
|
? Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) =>
|
themeProvider.select(
|
||||||
value.assets.stackIcon,
|
(value) => value
|
||||||
|
.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
width: 20,
|
width: 20,
|
||||||
|
@ -211,9 +215,11 @@ class ContactPopUp extends ConsumerWidget {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 2,
|
height: 2,
|
||||||
),
|
),
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
coinIconProvider(e.coin),
|
ref.watch(
|
||||||
|
coinIconProvider(e.coin),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/new_contact_address_entry_form.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/new_contact_address_entry_form.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
||||||
|
@ -49,7 +48,7 @@ class _EditContactAddressViewState
|
||||||
late final BarcodeScannerInterface barcodeScanner;
|
late final BarcodeScannerInterface barcodeScanner;
|
||||||
late final ClipboardInterface clipboard;
|
late final ClipboardInterface clipboard;
|
||||||
|
|
||||||
Future<void> save(Contact contact) async {
|
Future<void> save(ContactEntry contact) async {
|
||||||
if (FocusScope.of(context).hasFocus) {
|
if (FocusScope.of(context).hasFocus) {
|
||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context).unfocus();
|
||||||
await Future<void>.delayed(
|
await Future<void>.delayed(
|
||||||
|
@ -73,7 +72,7 @@ class _EditContactAddressViewState
|
||||||
|
|
||||||
entries.insert(index, editedEntry);
|
entries.insert(index, editedEntry);
|
||||||
|
|
||||||
Contact editedContact = contact.copyWith(addresses: entries);
|
ContactEntry editedContact = contact.copyWith(addresses: entries);
|
||||||
|
|
||||||
if (await ref.read(addressBookServiceProvider).editContact(editedContact)) {
|
if (await ref.read(addressBookServiceProvider).editContact(editedContact)) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
@ -226,7 +225,8 @@ class _EditContactAddressViewState
|
||||||
);
|
);
|
||||||
|
|
||||||
_addresses.remove(entry);
|
_addresses.remove(entry);
|
||||||
Contact editedContact = contact.copyWith(addresses: _addresses);
|
ContactEntry editedContact =
|
||||||
|
contact.copyWith(addresses: _addresses);
|
||||||
if (await ref
|
if (await ref
|
||||||
.read(addressBookServiceProvider)
|
.read(addressBookServiceProvider)
|
||||||
.editContact(editedContact)) {
|
.editContact(editedContact)) {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
@ -7,8 +9,8 @@ import 'package:stackwallet/pages/address_book_views/subviews/coin_select_sheet.
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
// import 'package:stackwallet/providers/global/should_show_lockscreen_on_resume_state_provider.dart';
|
// import 'package:stackwallet/providers/global/should_show_lockscreen_on_resume_state_provider.dart';
|
||||||
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/address_utils.dart';
|
import 'package:stackwallet/utilities/address_utils.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
|
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
|
||||||
|
@ -141,8 +143,10 @@ class _NewContactAddressEntryFormState
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(coin)),
|
||||||
|
),
|
||||||
height: 24,
|
height: 24,
|
||||||
width: 24,
|
width: 24,
|
||||||
),
|
),
|
||||||
|
@ -211,15 +215,17 @@ class _NewContactAddressEntryFormState
|
||||||
)
|
)
|
||||||
: Row(
|
: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
coinIconProvider(
|
ref.watch(
|
||||||
ref.watch(
|
coinIconProvider(
|
||||||
addressEntryDataProvider(widget.id)
|
ref.watch(
|
||||||
.select(
|
addressEntryDataProvider(widget.id)
|
||||||
(value) => value.coin,
|
.select(
|
||||||
),
|
(value) => value.coin,
|
||||||
)!,
|
),
|
||||||
|
)!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
height: 20,
|
height: 20,
|
||||||
|
|
|
@ -144,7 +144,7 @@ class _ReceiveViewState extends ConsumerState<ReceiveView> {
|
||||||
aspectRatio: 1,
|
aspectRatio: 1,
|
||||||
child: AppBarIconButton(
|
child: AppBarIconButton(
|
||||||
semanticsLabel:
|
semanticsLabel:
|
||||||
"Address List Pop-up Button. Opens A Pop-up For Adress List Button.",
|
"Address List Pop-up Button. Opens A Pop-up For Address List Button.",
|
||||||
key: const Key("walletNetworkSettingsAddNewNodeViewButton"),
|
key: const Key("walletNetworkSettingsAddNewNodeViewButton"),
|
||||||
size: 36,
|
size: 36,
|
||||||
shadows: const [],
|
shadows: const [],
|
||||||
|
|
|
@ -35,6 +35,12 @@ class _ManageExplorerViewState extends ConsumerState<ManageExplorerView> {
|
||||||
.replaceAll("%5BTXID%5D", "[TXID]"));
|
.replaceAll("%5BTXID%5D", "[TXID]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
textEditingController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Background(
|
return Background(
|
||||||
|
@ -93,13 +99,19 @@ class _ManageExplorerViewState extends ConsumerState<ManageExplorerView> {
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.getPrimaryEnabledButtonStyle(context),
|
.getPrimaryEnabledButtonStyle(context),
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
textEditingController.text =
|
textEditingController.text =
|
||||||
textEditingController.text.trim();
|
textEditingController.text.trim();
|
||||||
setBlockExplorerForCoin(
|
await setBlockExplorerForCoin(
|
||||||
coin: widget.coin,
|
coin: widget.coin,
|
||||||
url: Uri.parse(textEditingController.text))
|
url: Uri.parse(
|
||||||
.then((value) => Navigator.of(context).pop());
|
textEditingController.text,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
"Save",
|
"Save",
|
||||||
|
|
|
@ -191,7 +191,8 @@ class GlobalSettingsView extends StatelessWidget {
|
||||||
title: "Appearance",
|
title: "Appearance",
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
AppearanceSettingsView.routeName);
|
AppearanceSettingsView.routeName,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (Platform.isIOS)
|
if (Platform.isIOS)
|
||||||
|
|
|
@ -5,10 +5,9 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:stack_wallet_backup/stack_wallet_backup.dart';
|
import 'package:stack_wallet_backup/stack_wallet_backup.dart';
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
import 'package:stackwallet/db/hive/db.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
|
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
|
||||||
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
|
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/node_model.dart';
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
import 'package:stackwallet/models/stack_restoring_ui_state.dart';
|
import 'package:stackwallet/models/stack_restoring_ui_state.dart';
|
||||||
import 'package:stackwallet/models/trade_wallet_lookup.dart';
|
import 'package:stackwallet/models/trade_wallet_lookup.dart';
|
||||||
|
@ -266,7 +265,7 @@ abstract class SWB {
|
||||||
);
|
);
|
||||||
|
|
||||||
AddressBookService addressBookService = AddressBookService();
|
AddressBookService addressBookService = AddressBookService();
|
||||||
var addresses = await addressBookService.addressBookEntries;
|
var addresses = addressBookService.contacts;
|
||||||
backupJson['addressBookEntries'] =
|
backupJson['addressBookEntries'] =
|
||||||
addresses.map((e) => e.toMap()).toList();
|
addresses.map((e) => e.toMap()).toList();
|
||||||
|
|
||||||
|
@ -799,7 +798,7 @@ abstract class SWB {
|
||||||
|
|
||||||
// contacts
|
// contacts
|
||||||
final addressBookService = AddressBookService();
|
final addressBookService = AddressBookService();
|
||||||
final allContactIds = addressBookService.contacts.map((e) => e.id);
|
final allContactIds = addressBookService.contacts.map((e) => e.customId);
|
||||||
|
|
||||||
if (addressBookEntries == null) {
|
if (addressBookEntries == null) {
|
||||||
// if no contacts were present before attempted restore then delete any that
|
// if no contacts were present before attempted restore then delete any that
|
||||||
|
@ -823,21 +822,20 @@ abstract class SWB {
|
||||||
List<ContactAddressEntry> addresses = [];
|
List<ContactAddressEntry> addresses = [];
|
||||||
for (var address in (contact['addresses'] as List<dynamic>)) {
|
for (var address in (contact['addresses'] as List<dynamic>)) {
|
||||||
addresses.add(
|
addresses.add(
|
||||||
ContactAddressEntry(
|
ContactAddressEntry()
|
||||||
coin: Coin.values
|
..coinName = address['coin'] as String
|
||||||
.firstWhere((element) => element.name == address['coin']),
|
..address = address['address'] as String
|
||||||
address: address['address'] as String,
|
..label = address['label'] as String
|
||||||
label: address['label'] as String,
|
..other = address['other'] as String?,
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await addressBookService.editContact(
|
await addressBookService.editContact(
|
||||||
Contact(
|
ContactEntry(
|
||||||
emojiChar: contact['emoji'] as String?,
|
emojiChar: contact['emoji'] as String?,
|
||||||
name: contact['name'] as String,
|
name: contact['name'] as String,
|
||||||
addresses: addresses,
|
addresses: addresses,
|
||||||
isFavorite: contact['isFavorite'] as bool,
|
isFavorite: contact['isFavorite'] as bool,
|
||||||
id: contact['id'] as String,
|
customId: contact['id'] as String,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1026,21 +1024,20 @@ abstract class SWB {
|
||||||
List<ContactAddressEntry> addresses = [];
|
List<ContactAddressEntry> addresses = [];
|
||||||
for (var address in (contact['addresses'] as List<dynamic>)) {
|
for (var address in (contact['addresses'] as List<dynamic>)) {
|
||||||
addresses.add(
|
addresses.add(
|
||||||
ContactAddressEntry(
|
ContactAddressEntry()
|
||||||
coin: Coin.values
|
..coinName = address['coin'] as String
|
||||||
.firstWhere((element) => element.name == address['coin']),
|
..address = address['address'] as String
|
||||||
address: address['address'] as String,
|
..label = address['label'] as String
|
||||||
label: address['label'] as String,
|
..other = address['other'] as String?,
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await addressBookService.addContact(
|
await addressBookService.addContact(
|
||||||
Contact(
|
ContactEntry(
|
||||||
emojiChar: contact['emoji'] as String?,
|
emojiChar: contact['emoji'] as String?,
|
||||||
name: contact['name'] as String,
|
name: contact['name'] as String,
|
||||||
addresses: addresses,
|
addresses: addresses,
|
||||||
isFavorite: contact['isFavorite'] as bool,
|
isFavorite: contact['isFavorite'] as bool,
|
||||||
id: contact['id'] as String,
|
customId: contact['id'] as String,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
@ -6,8 +8,8 @@ import 'package:stackwallet/pages/settings_views/global_settings_view/stack_back
|
||||||
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart';
|
import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart';
|
||||||
import 'package:stackwallet/providers/stack_restore/stack_restoring_ui_state_provider.dart';
|
import 'package:stackwallet/providers/stack_restore/stack_restoring_ui_state_provider.dart';
|
||||||
import 'package:stackwallet/route_generator.dart';
|
import 'package:stackwallet/route_generator.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/enums/stack_restoring_status.dart';
|
import 'package:stackwallet/utilities/enums/stack_restoring_status.dart';
|
||||||
|
@ -81,8 +83,10 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> {
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.colorForCoin(coin),
|
.colorForCoin(coin),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(coin)),
|
||||||
|
),
|
||||||
height: 20,
|
height: 20,
|
||||||
width: 20,
|
width: 20,
|
||||||
),
|
),
|
||||||
|
@ -222,9 +226,11 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> {
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.colorForCoin(coin),
|
.colorForCoin(coin),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
coinIconProvider(coin),
|
ref.watch(
|
||||||
|
coinIconProvider(coin),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
height: 20,
|
height: 20,
|
||||||
width: 20,
|
width: 20,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:stackwallet/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart';
|
import 'package:stackwallet/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/widgets/background.dart';
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
|
@ -236,22 +238,24 @@ class _StartupPreferencesViewState
|
||||||
.only(top: 12),
|
.only(top: 12),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
coinIconProvider(
|
ref.watch(
|
||||||
ref
|
coinIconProvider(
|
||||||
.watch(
|
ref
|
||||||
walletsChangeNotifierProvider
|
.watch(
|
||||||
.select(
|
walletsChangeNotifierProvider
|
||||||
(value) =>
|
.select(
|
||||||
value.getManager(
|
(value) =>
|
||||||
ref.watch(
|
value.getManager(
|
||||||
prefsChangeNotifierProvider.select((value) => value.startupWalletId!),
|
ref.watch(
|
||||||
|
prefsChangeNotifierProvider.select((value) => value.startupWalletId!),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
.coin,
|
||||||
.coin,
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
import 'package:stackwallet/widgets/background.dart';
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
|
@ -102,9 +104,11 @@ class _StartupWalletSelectionViewState
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
coinIconProvider(manager.coin),
|
ref.watch(
|
||||||
|
coinIconProvider(manager.coin),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
|
import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
|
||||||
|
@ -116,9 +118,11 @@ class WalletSyncingOptionsView extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
coinIconProvider(manager.coin),
|
ref.watch(
|
||||||
|
coinIconProvider(manager.coin),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
|
|
|
@ -8,7 +8,6 @@ import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/manager.dart';
|
import 'package:stackwallet/services/coins/manager.dart';
|
||||||
import 'package:stackwallet/services/mixins/xpubable.dart';
|
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
||||||
|
@ -177,7 +176,7 @@ class _XPubViewState extends ConsumerState<XPubView> {
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
child: FutureBuilder(
|
child: FutureBuilder(
|
||||||
future: (manager.wallet as XPubAble).xpub,
|
future: manager.xpub,
|
||||||
builder: (context, AsyncSnapshot<String> snapshot) {
|
builder: (context, AsyncSnapshot<String> snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.done &&
|
if (snapshot.connectionState == ConnectionState.done &&
|
||||||
snapshot.hasData) {
|
snapshot.hasData) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
/// [eventBus] should only be set during testing
|
/// [eventBus] should only be set during testing
|
||||||
class WalletSettingsView extends StatefulWidget {
|
class WalletSettingsView extends ConsumerStatefulWidget {
|
||||||
const WalletSettingsView({
|
const WalletSettingsView({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.walletId,
|
required this.walletId,
|
||||||
|
@ -52,10 +52,10 @@ class WalletSettingsView extends StatefulWidget {
|
||||||
final EventBus? eventBus;
|
final EventBus? eventBus;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<WalletSettingsView> createState() => _WalletSettingsViewState();
|
ConsumerState<WalletSettingsView> createState() => _WalletSettingsViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WalletSettingsViewState extends State<WalletSettingsView> {
|
class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
|
||||||
late final String walletId;
|
late final String walletId;
|
||||||
late final Coin coin;
|
late final Coin coin;
|
||||||
late String xpub;
|
late String xpub;
|
||||||
|
@ -74,7 +74,7 @@ class _WalletSettingsViewState extends State<WalletSettingsView> {
|
||||||
walletId = widget.walletId;
|
walletId = widget.walletId;
|
||||||
coin = widget.coin;
|
coin = widget.coin;
|
||||||
xPubEnabled =
|
xPubEnabled =
|
||||||
coin != Coin.monero && coin != Coin.wownero && coin != Coin.epicCash;
|
ref.read(walletsChangeNotifierProvider).getManager(walletId).hasXPub;
|
||||||
xpub = "";
|
xpub = "";
|
||||||
|
|
||||||
_currentSyncStatus = widget.initialSyncStatus;
|
_currentSyncStatus = widget.initialSyncStatus;
|
||||||
|
|
|
@ -308,14 +308,23 @@ class TokenOptionsButton extends StatelessWidget {
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: SvgPicture.file(
|
child: iconAssetPathSVG.startsWith("assets/")
|
||||||
File(iconAssetPathSVG),
|
? SvgPicture.asset(
|
||||||
color: Theme.of(context)
|
iconAssetPathSVG,
|
||||||
.extension<StackColors>()!
|
color: Theme.of(context)
|
||||||
.tokenSummaryIcon,
|
.extension<StackColors>()!
|
||||||
width: iconSize,
|
.tokenSummaryIcon,
|
||||||
height: iconSize,
|
width: iconSize,
|
||||||
),
|
height: iconSize,
|
||||||
|
)
|
||||||
|
: SvgPicture.file(
|
||||||
|
File(iconAssetPathSVG),
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.tokenSummaryIcon,
|
||||||
|
width: iconSize,
|
||||||
|
height: iconSize,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -23,19 +23,6 @@ class TxIcon extends ConsumerWidget {
|
||||||
|
|
||||||
static const Size size = Size(32, 32);
|
static const Size size = Size(32, 32);
|
||||||
|
|
||||||
// String _getBundleAssetName(
|
|
||||||
// bool isCancelled, bool isReceived, bool isPending, BuildContext context) {
|
|
||||||
// if (!isReceived && transaction.subType == TransactionSubType.mint) {
|
|
||||||
// if (isCancelled) {
|
|
||||||
// return Assets.svg.anonymizeFailed;
|
|
||||||
// }
|
|
||||||
// if (isPending) {
|
|
||||||
// return Assets.svg.anonymizePending;
|
|
||||||
// }
|
|
||||||
// return Assets.svg.anonymize;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
String _getAssetName(
|
String _getAssetName(
|
||||||
bool isCancelled, bool isReceived, bool isPending, ThemeAssets assets) {
|
bool isCancelled, bool isReceived, bool isPending, ThemeAssets assets) {
|
||||||
if (!isReceived && transaction.subType == TransactionSubType.mint) {
|
if (!isReceived && transaction.subType == TransactionSubType.mint) {
|
||||||
|
|
|
@ -3,8 +3,8 @@ import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/transaction_filter.dart';
|
import 'package:stackwallet/models/transaction_filter.dart';
|
||||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||||
import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart';
|
import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart';
|
||||||
|
@ -120,8 +120,8 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isKeywordMatch(Transaction tx, String keyword, List<Contact> contacts,
|
bool _isKeywordMatch(Transaction tx, String keyword,
|
||||||
Map<String, String> notes) {
|
List<ContactEntry> contacts, Map<String, String> notes) {
|
||||||
if (keyword.isEmpty) {
|
if (keyword.isEmpty) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart';
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/address_book_filter_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/address_book_view/subwidgets/desktop_address_book_scaffold.dart';
|
import 'package:stackwallet/pages_desktop_specific/address_book_view/subwidgets/desktop_address_book_scaffold.dart';
|
||||||
|
@ -105,19 +104,18 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
|
||||||
final managers = ref.read(walletsChangeNotifierProvider).managers;
|
final managers = ref.read(walletsChangeNotifierProvider).managers;
|
||||||
for (final manager in managers) {
|
for (final manager in managers) {
|
||||||
addresses.add(
|
addresses.add(
|
||||||
ContactAddressEntry(
|
ContactAddressEntry()
|
||||||
coin: manager.coin,
|
..coinName = manager.coin.name
|
||||||
address: await manager.currentReceivingAddress,
|
..address = await manager.currentReceivingAddress
|
||||||
label: "Current Receiving",
|
..label = "Current Receiving"
|
||||||
other: manager.walletName,
|
..other = manager.walletName,
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final self = Contact(
|
final self = ContactEntry(
|
||||||
name: "My Stack",
|
name: "My Stack",
|
||||||
addresses: addresses,
|
addresses: addresses,
|
||||||
isFavorite: true,
|
isFavorite: true,
|
||||||
id: "default",
|
customId: "default",
|
||||||
);
|
);
|
||||||
await ref.read(addressBookServiceProvider).editContact(self);
|
await ref.read(addressBookServiceProvider).editContact(self);
|
||||||
});
|
});
|
||||||
|
@ -323,14 +321,14 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.accentColorDark
|
.accentColorDark
|
||||||
.withOpacity(
|
.withOpacity(
|
||||||
currentContactId == favorites[i].id
|
currentContactId == favorites[i].customId
|
||||||
? 0.08
|
? 0.08
|
||||||
: 0,
|
: 0,
|
||||||
),
|
),
|
||||||
child: RawMaterialButton(
|
child: RawMaterialButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
currentContactId = favorites[i].id;
|
currentContactId = favorites[i].customId;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
|
@ -346,8 +344,8 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
|
||||||
),
|
),
|
||||||
child: AddressBookCard(
|
child: AddressBookCard(
|
||||||
key: Key(
|
key: Key(
|
||||||
"favContactCard_${favorites[i].id}_key"),
|
"favContactCard_${favorites[i].customId}_key"),
|
||||||
contactId: favorites[i].id,
|
contactId: favorites[i].customId,
|
||||||
desktopSendFrom: false,
|
desktopSendFrom: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -393,14 +391,16 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.accentColorDark
|
.accentColorDark
|
||||||
.withOpacity(
|
.withOpacity(
|
||||||
currentContactId == allContacts[i].id
|
currentContactId ==
|
||||||
|
allContacts[i].customId
|
||||||
? 0.08
|
? 0.08
|
||||||
: 0,
|
: 0,
|
||||||
),
|
),
|
||||||
child: RawMaterialButton(
|
child: RawMaterialButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
currentContactId = allContacts[i].id;
|
currentContactId =
|
||||||
|
allContacts[i].customId;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
|
@ -416,8 +416,8 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
|
||||||
),
|
),
|
||||||
child: AddressBookCard(
|
child: AddressBookCard(
|
||||||
key: Key(
|
key: Key(
|
||||||
"favContactCard_${allContacts[i].id}_key"),
|
"favContactCard_${allContacts[i].customId}_key"),
|
||||||
contactId: allContacts[i].id,
|
contactId: allContacts[i].customId,
|
||||||
desktopSendFrom: false,
|
desktopSendFrom: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_address_view.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_address_view.dart';
|
||||||
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/add_new_contact_address_view.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/add_new_contact_address_view.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart';
|
import 'package:stackwallet/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart';
|
||||||
|
@ -24,8 +27,6 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
import 'package:stackwallet/widgets/transaction_card.dart';
|
import 'package:stackwallet/widgets/transaction_card.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
import '../../../db/isar/main_db.dart';
|
|
||||||
|
|
||||||
class DesktopContactDetails extends ConsumerStatefulWidget {
|
class DesktopContactDetails extends ConsumerStatefulWidget {
|
||||||
const DesktopContactDetails({
|
const DesktopContactDetails({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -42,7 +43,7 @@ class DesktopContactDetails extends ConsumerStatefulWidget {
|
||||||
class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
|
class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
|
||||||
List<Tuple2<String, Transaction>> _cachedTransactions = [];
|
List<Tuple2<String, Transaction>> _cachedTransactions = [];
|
||||||
|
|
||||||
bool _contactHasAddress(String address, Contact contact) {
|
bool _contactHasAddress(String address, ContactEntry contact) {
|
||||||
for (final entry in contact.addresses) {
|
for (final entry in contact.addresses) {
|
||||||
if (entry.address == address) {
|
if (entry.address == address) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,7 +83,7 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// provider hack to prevent trying to update widget with deleted contact
|
// provider hack to prevent trying to update widget with deleted contact
|
||||||
Contact? _contact;
|
ContactEntry? _contact;
|
||||||
try {
|
try {
|
||||||
_contact = ref.watch(addressBookServiceProvider
|
_contact = ref.watch(addressBookServiceProvider
|
||||||
.select((value) => value.getContactById(widget.contactId)));
|
.select((value) => value.getContactById(widget.contactId)));
|
||||||
|
@ -117,12 +118,14 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
|
||||||
.textFieldDefaultBG,
|
.textFieldDefaultBG,
|
||||||
borderRadius: BorderRadius.circular(32),
|
borderRadius: BorderRadius.circular(32),
|
||||||
),
|
),
|
||||||
child: contact.id == "default"
|
child: contact.customId == "default"
|
||||||
? Center(
|
? Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.stackIcon,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
width: 32,
|
width: 32,
|
||||||
|
@ -159,7 +162,7 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
|
||||||
barrierColor: Colors.transparent,
|
barrierColor: Colors.transparent,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return DesktopContactOptionsMenuPopup(
|
return DesktopContactOptionsMenuPopup(
|
||||||
contactId: contact.id,
|
contactId: contact.customId,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -261,7 +264,7 @@ class _DesktopContactDetailsState extends ConsumerState<DesktopContactDetails> {
|
||||||
padding: const EdgeInsets.all(18),
|
padding: const EdgeInsets.all(18),
|
||||||
child: DesktopAddressCard(
|
child: DesktopAddressCard(
|
||||||
entry: contact.addresses[i],
|
entry: contact.addresses[i],
|
||||||
contactId: contact.id,
|
contactId: contact.customId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -147,7 +147,7 @@ class _DesktopContactOptionsMenuPopupState
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ref
|
ref
|
||||||
.read(addressBookServiceProvider)
|
.read(addressBookServiceProvider)
|
||||||
.removeContact(contact.id);
|
.removeContact(contact.customId);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
showFloatingFlushBar(
|
showFloatingFlushBar(
|
||||||
type: FlushBarType.success,
|
type: FlushBarType.success,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
@ -6,8 +8,8 @@ import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/coin_control/utxo_row.dart';
|
import 'package:stackwallet/pages_desktop_specific/coin_control/utxo_row.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
@ -359,8 +361,10 @@ class _DesktopCoinControlUseDialogState
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(coin)),
|
||||||
|
),
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
@ -7,8 +9,8 @@ import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/coin_control/freeze_button.dart';
|
import 'package:stackwallet/pages_desktop_specific/coin_control/freeze_button.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/coin_control/utxo_row.dart';
|
import 'package:stackwallet/pages_desktop_specific/coin_control/utxo_row.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
@ -343,8 +345,10 @@ class _DesktopCoinControlViewState
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(coin)),
|
||||||
|
),
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -522,10 +523,14 @@ class _DesktopTradeRowCardState extends ConsumerState<DesktopTradeRowCard> {
|
||||||
borderRadius: BorderRadius.circular(32),
|
borderRadius: BorderRadius.circular(32),
|
||||||
),
|
),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
_fetchIconAssetForStatus(
|
File(
|
||||||
trade.status,
|
_fetchIconAssetForStatus(
|
||||||
ref.watch(themeProvider.select((value) => value.assets)),
|
trade.status,
|
||||||
|
ref.watch(
|
||||||
|
themeProvider.select((value) => value.assets),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
@ -81,28 +83,36 @@ class DesktopNotificationsIcon extends ConsumerWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return SvgPicture.asset(
|
return ref.watch(notificationsProvider
|
||||||
ref.watch(notificationsProvider
|
.select((value) => value.hasUnreadNotifications))
|
||||||
.select((value) => value.hasUnreadNotifications))
|
? SvgPicture.file(
|
||||||
? ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.bellNew,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.bellNew,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
: Assets.svg.bell,
|
width: 20,
|
||||||
width: 20,
|
height: 20,
|
||||||
height: 20,
|
)
|
||||||
color: ref.watch(notificationsProvider
|
: SvgPicture.asset(
|
||||||
.select((value) => value.hasUnreadNotifications))
|
Assets.svg.bell,
|
||||||
? null
|
width: 20,
|
||||||
: DesktopMenuItemId.notifications ==
|
height: 20,
|
||||||
ref.watch(currentDesktopMenuItemProvider.state).state
|
color: ref.watch(notificationsProvider
|
||||||
? Theme.of(context).extension<StackColors>()!.accentColorDark
|
.select((value) => value.hasUnreadNotifications))
|
||||||
: Theme.of(context)
|
? null
|
||||||
.extension<StackColors>()!
|
: DesktopMenuItemId.notifications ==
|
||||||
.accentColorDark
|
ref.watch(currentDesktopMenuItemProvider.state).state
|
||||||
.withOpacity(0.8),
|
? Theme.of(context)
|
||||||
);
|
.extension<StackColors>()!
|
||||||
|
.accentColorDark
|
||||||
|
: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.accentColorDark
|
||||||
|
.withOpacity(0.8),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
@ -53,10 +55,12 @@ class DesktopMyStackTitle extends ConsumerWidget {
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.stackIcon,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
@ -10,8 +12,8 @@ import 'package:stackwallet/providers/global/price_provider.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
|
import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
|
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
|
||||||
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
import 'package:stackwallet/utilities/clipboard_interface.dart';
|
||||||
|
@ -81,8 +83,10 @@ class _DesktopPaynymSendDialogState
|
||||||
// Theme.of(context).extension<StackColors>()!.textSubtitle4,
|
// Theme.of(context).extension<StackColors>()!.textSubtitle4,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(coin)),
|
||||||
|
),
|
||||||
width: 36,
|
width: 36,
|
||||||
height: 36,
|
height: 36,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/pages/wallets_view/wallets_overview.dart';
|
import 'package:stackwallet/pages/wallets_view/wallets_overview.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
@ -141,8 +143,10 @@ class _DesktopWalletSummaryRowState
|
||||||
flex: 4,
|
flex: 4,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(widget.coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(widget.coin)),
|
||||||
|
),
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart';
|
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
@ -34,7 +34,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
|
||||||
|
|
||||||
String _searchTerm = "";
|
String _searchTerm = "";
|
||||||
|
|
||||||
int _compareContactFavorite(Contact a, Contact b) {
|
int _compareContactFavorite(ContactEntry a, ContactEntry b) {
|
||||||
if (a.isFavorite && b.isFavorite) {
|
if (a.isFavorite && b.isFavorite) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (a.isFavorite) {
|
} else if (a.isFavorite) {
|
||||||
|
@ -44,8 +44,8 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Contact> pullOutFavorites(List<Contact> contacts) {
|
List<ContactEntry> pullOutFavorites(List<ContactEntry> contacts) {
|
||||||
final List<Contact> favorites = [];
|
final List<ContactEntry> favorites = [];
|
||||||
contacts.removeWhere((contact) {
|
contacts.removeWhere((contact) {
|
||||||
if (contact.isFavorite) {
|
if (contact.isFavorite) {
|
||||||
favorites.add(contact);
|
favorites.add(contact);
|
||||||
|
@ -57,7 +57,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
|
||||||
return favorites;
|
return favorites;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Contact> filter(List<Contact> contacts, String searchTerm) {
|
List<ContactEntry> filter(List<ContactEntry> contacts, String searchTerm) {
|
||||||
if (widget.coin != null) {
|
if (widget.coin != null) {
|
||||||
contacts.removeWhere(
|
contacts.removeWhere(
|
||||||
(e) => e.addresses.where((a) => a.coin == widget.coin!).isEmpty);
|
(e) => e.addresses.where((a) => a.coin == widget.coin!).isEmpty);
|
||||||
|
@ -75,7 +75,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
|
||||||
return contacts;
|
return contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _matches(String term, Contact contact) {
|
bool _matches(String term, ContactEntry contact) {
|
||||||
final text = term.toLowerCase();
|
final text = term.toLowerCase();
|
||||||
if (contact.name.toLowerCase().contains(text)) {
|
if (contact.name.toLowerCase().contains(text)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -191,7 +191,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
|
||||||
),
|
),
|
||||||
child: Consumer(
|
child: Consumer(
|
||||||
builder: (context, ref, _) {
|
builder: (context, ref, _) {
|
||||||
List<Contact> contacts = ref
|
List<ContactEntry> contacts = ref
|
||||||
.watch(addressBookServiceProvider
|
.watch(addressBookServiceProvider
|
||||||
.select((value) => value.contacts))
|
.select((value) => value.contacts))
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -228,7 +228,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (index < favorites.length + 1) {
|
} else if (index < favorites.length + 1) {
|
||||||
final id = favorites[index - 1].id;
|
final id = favorites[index - 1].customId;
|
||||||
return ContactListItem(
|
return ContactListItem(
|
||||||
key: Key("contactContactListItem_${id}_key"),
|
key: Key("contactContactListItem_${id}_key"),
|
||||||
contactId: id,
|
contactId: id,
|
||||||
|
@ -248,7 +248,8 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final id = contacts[index - favorites.length - 2].id;
|
final id =
|
||||||
|
contacts[index - favorites.length - 2].customId;
|
||||||
return ContactListItem(
|
return ContactListItem(
|
||||||
key: Key("contactContactListItem_${id}_key"),
|
key: Key("contactContactListItem_${id}_key"),
|
||||||
contactId: id,
|
contactId: id,
|
||||||
|
|
|
@ -94,10 +94,12 @@ class _ForgotPasswordDesktopViewState
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.stackIcon,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
width: 100,
|
width: 100,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
@ -54,7 +55,7 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
|
||||||
int dbVersion = DB.instance.get<dynamic>(
|
int dbVersion = DB.instance.get<dynamic>(
|
||||||
boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
|
boxName: DB.boxNameDBInfo, key: "hive_data_version") as int? ??
|
||||||
0;
|
0;
|
||||||
if (dbVersion < Constants.currentHiveDbVersion) {
|
if (dbVersion < Constants.currentDataVersion) {
|
||||||
try {
|
try {
|
||||||
await DbVersionMigrator().migrate(
|
await DbVersionMigrator().migrate(
|
||||||
dbVersion,
|
dbVersion,
|
||||||
|
@ -166,10 +167,12 @@ class _DesktopLoginViewState extends ConsumerState<DesktopLoginView> {
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.stackIcon,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
width: 100,
|
width: 100,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
@ -47,10 +49,12 @@ class _ForgotPasswordDesktopViewState
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.stackIcon,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
width: 100,
|
width: 100,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/advanced_settings/debug_info_dialog.dart';
|
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/advanced_settings/debug_info_dialog.dart';
|
||||||
|
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/advanced_settings/desktop_manage_block_explorers_dialog.dart';
|
||||||
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/advanced_settings/stack_privacy_dialog.dart';
|
import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/advanced_settings/stack_privacy_dialog.dart';
|
||||||
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
@ -58,7 +59,7 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
|
||||||
),
|
),
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text:
|
text:
|
||||||
"\n\nConfigurate these settings only if you know what you are doing!",
|
"\n\nConfigure these settings only if you know what you are doing!",
|
||||||
style: STextStyles.desktopTextExtraExtraSmall(
|
style: STextStyles.desktopTextExtraExtraSmall(
|
||||||
context),
|
context),
|
||||||
),
|
),
|
||||||
|
@ -183,7 +184,7 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
|
||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
label: "Change",
|
label: "Change",
|
||||||
buttonHeight: ButtonHeight.xs,
|
buttonHeight: ButtonHeight.xs,
|
||||||
width: 86,
|
width: 101,
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await showDialog<dynamic>(
|
await showDialog<dynamic>(
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -207,8 +208,6 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
|
||||||
thickness: 0.5,
|
thickness: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
/// TODO: Make a dialog popup
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
@ -241,6 +240,44 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.all(10.0),
|
||||||
|
child: Divider(
|
||||||
|
thickness: 0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Block explorers",
|
||||||
|
style: STextStyles.desktopTextExtraSmall(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textDark),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
PrimaryButton(
|
||||||
|
buttonHeight: ButtonHeight.xs,
|
||||||
|
label: "Edit",
|
||||||
|
width: 101,
|
||||||
|
onPressed: () async {
|
||||||
|
await showDialog<dynamic>(
|
||||||
|
context: context,
|
||||||
|
useSafeArea: false,
|
||||||
|
barrierDismissible: true,
|
||||||
|
builder: (context) {
|
||||||
|
return const DesktopManageBlockExplorersDialog();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/providers/global/prefs_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/block_explorers.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
|
class DesktopManageBlockExplorersDialog extends ConsumerWidget {
|
||||||
|
const DesktopManageBlockExplorersDialog({
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
bool showTestNet = ref.watch(
|
||||||
|
prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<Coin> coins = showTestNet
|
||||||
|
? Coin.values
|
||||||
|
: Coin.values.sublist(0, Coin.values.length - kTestNetCoinCount);
|
||||||
|
|
||||||
|
return DesktopDialog(
|
||||||
|
maxHeight: 850,
|
||||||
|
maxWidth: 600,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(32),
|
||||||
|
child: Text(
|
||||||
|
"Manage block explorers",
|
||||||
|
style: STextStyles.desktopH3(context),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const DesktopDialogCloseButton(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 32,
|
||||||
|
right: 32,
|
||||||
|
bottom: 32,
|
||||||
|
),
|
||||||
|
child: ListView.separated(
|
||||||
|
itemCount: coins.length,
|
||||||
|
separatorBuilder: (_, __) => const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
final coin = coins[index];
|
||||||
|
|
||||||
|
return RoundedWhiteContainer(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 16,
|
||||||
|
horizontal: 14,
|
||||||
|
),
|
||||||
|
borderColor: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle6,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SvgPicture.file(
|
||||||
|
File(
|
||||||
|
ref.watch(coinIconProvider(coin)),
|
||||||
|
),
|
||||||
|
width: 24,
|
||||||
|
height: 24,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
"${coin.prettyName} block explorer",
|
||||||
|
style: STextStyles.desktopTextSmall(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 12,
|
||||||
|
),
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.svg.chevronRight,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
showDialog<dynamic>(
|
||||||
|
context: context,
|
||||||
|
useSafeArea: false,
|
||||||
|
barrierDismissible: true,
|
||||||
|
builder: (context) {
|
||||||
|
return _DesktopEditBlockExplorerDialog(
|
||||||
|
coin: coin,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DesktopEditBlockExplorerDialog extends ConsumerStatefulWidget {
|
||||||
|
const _DesktopEditBlockExplorerDialog({Key? key, required this.coin})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
final Coin coin;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<_DesktopEditBlockExplorerDialog> createState() =>
|
||||||
|
_DesktopEditBlockExplorerDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DesktopEditBlockExplorerDialogState
|
||||||
|
extends ConsumerState<_DesktopEditBlockExplorerDialog> {
|
||||||
|
late final TextEditingController _textEditingController;
|
||||||
|
late final FocusNode _focusNode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_textEditingController = TextEditingController(
|
||||||
|
text:
|
||||||
|
getBlockExplorerTransactionUrlFor(coin: widget.coin, txid: "[TXID]")
|
||||||
|
.toString()
|
||||||
|
.replaceAll("%5BTXID%5D", "[TXID]"));
|
||||||
|
_focusNode = FocusNode();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_textEditingController.dispose();
|
||||||
|
_focusNode.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DesktopDialog(
|
||||||
|
maxHeight: double.infinity,
|
||||||
|
maxWidth: 600,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(32),
|
||||||
|
child: Text(
|
||||||
|
"${widget.coin.prettyName} block explorer",
|
||||||
|
style: STextStyles.desktopH3(context),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const DesktopDialogCloseButton(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
left: 32,
|
||||||
|
right: 32,
|
||||||
|
bottom: 32,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
child: TextField(
|
||||||
|
autocorrect: false,
|
||||||
|
enableSuggestions: false,
|
||||||
|
key: const Key("addCustomNodeNodeAddressFieldKey"),
|
||||||
|
controller: _textEditingController,
|
||||||
|
focusNode: _focusNode,
|
||||||
|
style: STextStyles.field(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
RoundedWhiteContainer(
|
||||||
|
borderColor:
|
||||||
|
Theme.of(context).extension<StackColors>()!.textSubtitle6,
|
||||||
|
child: Text(
|
||||||
|
"Edit your block explorer above. Keep in mind that"
|
||||||
|
" every block explorer has a slightly different URL scheme."
|
||||||
|
"\n\n"
|
||||||
|
"Paste in your block explorer of choice, then edit in"
|
||||||
|
" [TXID] where the transaction ID should go, and Stack"
|
||||||
|
" Wallet will auto fill the transaction ID in that place"
|
||||||
|
" of the URL.",
|
||||||
|
style: STextStyles.desktopTextExtraExtraSmall(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: SecondaryButton(
|
||||||
|
label: "Cancel",
|
||||||
|
buttonHeight: ButtonHeight.l,
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 16,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: PrimaryButton(
|
||||||
|
label: "Save",
|
||||||
|
buttonHeight: ButtonHeight.l,
|
||||||
|
onPressed: () async {
|
||||||
|
_textEditingController.text =
|
||||||
|
_textEditingController.text.trim();
|
||||||
|
await setBlockExplorerForCoin(
|
||||||
|
coin: widget.coin,
|
||||||
|
url: Uri.parse(
|
||||||
|
_textEditingController.text,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,8 +6,8 @@ import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
|
import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/route_generator.dart';
|
import 'package:stackwallet/route_generator.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
|
||||||
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
import 'package:stackwallet/themes/coin_icon_provider.dart';
|
||||||
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
@ -250,8 +250,10 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.file(
|
||||||
ref.watch(coinIconProvider(coin)),
|
File(
|
||||||
|
ref.watch(coinIconProvider(coin)),
|
||||||
|
),
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
|
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
|
||||||
import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart';
|
import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart';
|
||||||
import 'package:stackwallet/models/buy/response_objects/quote.dart';
|
import 'package:stackwallet/models/buy/response_objects/quote.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
|
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
|
||||||
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
|
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
|
@ -153,6 +152,8 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/widgets/choose_coin_view.dart';
|
import 'package:stackwallet/widgets/choose_coin_view.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
import 'models/isar/models/contact_entry.dart';
|
||||||
|
|
||||||
class RouteGenerator {
|
class RouteGenerator {
|
||||||
static const bool useMaterialPageRoute = true;
|
static const bool useMaterialPageRoute = true;
|
||||||
|
|
||||||
|
|
|
@ -1,55 +1,33 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
|
||||||
|
|
||||||
class AddressBookService extends ChangeNotifier {
|
class AddressBookService extends ChangeNotifier {
|
||||||
Contact getContactById(String id) {
|
ContactEntry getContactById(String id) {
|
||||||
final json = DB.instance
|
ContactEntry? contactEntry = MainDB.instance.getContactEntry(id: id);
|
||||||
.get<dynamic>(boxName: DB.boxNameAddressBook, key: id) as Map?;
|
if (contactEntry == null) {
|
||||||
if (json == null) {
|
|
||||||
Logging.instance
|
|
||||||
.log("Attempted to get non existing contact", level: LogLevel.Fatal);
|
|
||||||
throw Exception('Contact ID "$id" not found!');
|
throw Exception('Contact ID "$id" not found!');
|
||||||
|
} else {
|
||||||
|
return contactEntry;
|
||||||
}
|
}
|
||||||
return Contact.fromJson(Map<String, dynamic>.from(json));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Contact> get contacts {
|
List<ContactEntry> get contacts => MainDB.instance.getContactEntries();
|
||||||
final keys = List<String>.from(
|
|
||||||
DB.instance.keys<dynamic>(boxName: DB.boxNameAddressBook));
|
|
||||||
final _contacts = keys
|
|
||||||
.map((id) => Contact.fromJson(Map<String, dynamic>.from(DB.instance
|
|
||||||
.get<dynamic>(boxName: DB.boxNameAddressBook, key: id) as Map)))
|
|
||||||
.toList(growable: false);
|
|
||||||
_contacts
|
|
||||||
.sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
|
|
||||||
return _contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<Contact>>? _addressBookEntries;
|
|
||||||
Future<List<Contact>> get addressBookEntries =>
|
|
||||||
_addressBookEntries ??= _fetchAddressBookEntries();
|
|
||||||
|
|
||||||
// Load address book contact entries
|
|
||||||
Future<List<Contact>> _fetchAddressBookEntries() async {
|
|
||||||
return contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// search address book entries
|
/// search address book entries
|
||||||
//TODO optimize address book search?
|
//TODO search using isar queries
|
||||||
Future<List<Contact>> search(String text) async {
|
Future<List<ContactEntry>> search(String text) async {
|
||||||
if (text.isEmpty) return addressBookEntries;
|
if (text.isEmpty) return contacts;
|
||||||
var results = (await addressBookEntries).toList();
|
var results = contacts.toList();
|
||||||
|
|
||||||
results.retainWhere((contact) => matches(text, contact));
|
results.retainWhere((contact) => matches(text, contact));
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool matches(String term, Contact contact) {
|
bool matches(String term, ContactEntry contact) {
|
||||||
if (term.isEmpty) {
|
if (term.isEmpty) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -73,44 +51,27 @@ class AddressBookService extends ChangeNotifier {
|
||||||
///
|
///
|
||||||
/// returns false if it provided [contact]'s id already exists in the database
|
/// returns false if it provided [contact]'s id already exists in the database
|
||||||
/// other true if the [contact] was saved
|
/// other true if the [contact] was saved
|
||||||
Future<bool> addContact(Contact contact) async {
|
Future<bool> addContact(ContactEntry contact) async {
|
||||||
if (DB.instance.containsKey<dynamic>(
|
if (await MainDB.instance.isContactEntryExists(id: contact.customId)) {
|
||||||
boxName: DB.boxNameAddressBook, key: contact.id)) {
|
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
await MainDB.instance.putContactEntry(contactEntry: contact);
|
||||||
|
notifyListeners();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: DB.boxNameAddressBook,
|
|
||||||
key: contact.id,
|
|
||||||
value: contact.toMap());
|
|
||||||
|
|
||||||
Logging.instance.log("add address book entry saved", level: LogLevel.Info);
|
|
||||||
await _refreshAddressBookEntries();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Edit contact
|
/// Edit contact
|
||||||
Future<bool> editContact(Contact editedContact) async {
|
Future<bool> editContact(ContactEntry editedContact) async {
|
||||||
// over write the contact with edited version
|
// over write the contact with edited version
|
||||||
await DB.instance.put<dynamic>(
|
await MainDB.instance.putContactEntry(contactEntry: editedContact);
|
||||||
boxName: DB.boxNameAddressBook,
|
notifyListeners();
|
||||||
key: editedContact.id,
|
|
||||||
value: editedContact.toMap());
|
|
||||||
|
|
||||||
Logging.instance.log("edit address book entry saved", level: LogLevel.Info);
|
|
||||||
await _refreshAddressBookEntries();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove address book contact entry from db if it exists
|
/// Remove address book contact entry from db if it exists
|
||||||
Future<void> removeContact(String id) async {
|
Future<void> removeContact(String id) async {
|
||||||
await DB.instance.delete<dynamic>(key: id, boxName: DB.boxNameAddressBook);
|
await MainDB.instance.deleteContactEntry(id: id);
|
||||||
await _refreshAddressBookEntries();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _refreshAddressBookEntries() async {
|
|
||||||
final newAddressBookEntries = await _fetchAddressBookEntries();
|
|
||||||
_addressBookEntries = Future(() => newAddressBookEntries);
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,11 +53,11 @@ import 'package:uuid/uuid.dart';
|
||||||
const int MINIMUM_CONFIRMATIONS = 1;
|
const int MINIMUM_CONFIRMATIONS = 1;
|
||||||
final Amount DUST_LIMIT = Amount(
|
final Amount DUST_LIMIT = Amount(
|
||||||
rawValue: BigInt.from(294),
|
rawValue: BigInt.from(294),
|
||||||
fractionDigits: Coin.particl.decimals,
|
fractionDigits: Coin.bitcoin.decimals,
|
||||||
);
|
);
|
||||||
final Amount DUST_LIMIT_P2PKH = Amount(
|
final Amount DUST_LIMIT_P2PKH = Amount(
|
||||||
rawValue: BigInt.from(546),
|
rawValue: BigInt.from(546),
|
||||||
fractionDigits: Coin.particl.decimals,
|
fractionDigits: Coin.bitcoin.decimals,
|
||||||
);
|
);
|
||||||
|
|
||||||
const String GENESIS_HASH_MAINNET =
|
const String GENESIS_HASH_MAINNET =
|
||||||
|
|
|
@ -71,7 +71,6 @@ String constructDerivePath({
|
||||||
case 0x80: // bch mainnet wif
|
case 0x80: // bch mainnet wif
|
||||||
switch (derivePathType) {
|
switch (derivePathType) {
|
||||||
case DerivePathType.bip44:
|
case DerivePathType.bip44:
|
||||||
case DerivePathType.bip49:
|
|
||||||
coinType = 145; // bch mainnet
|
coinType = 145; // bch mainnet
|
||||||
break;
|
break;
|
||||||
case DerivePathType.bch44: // bitcoin.com wallet specific
|
case DerivePathType.bch44: // bitcoin.com wallet specific
|
||||||
|
@ -95,9 +94,6 @@ String constructDerivePath({
|
||||||
case DerivePathType.bch44:
|
case DerivePathType.bch44:
|
||||||
purpose = 44;
|
purpose = 44;
|
||||||
break;
|
break;
|
||||||
case DerivePathType.bip49:
|
|
||||||
purpose = 49;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw Exception("DerivePathType $derivePathType not supported");
|
throw Exception("DerivePathType $derivePathType not supported");
|
||||||
}
|
}
|
||||||
|
@ -283,10 +279,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
return DerivePathType.bip44;
|
return DerivePathType.bip44;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decodeBase58[0] == _network.scriptHash) {
|
|
||||||
// P2SH
|
|
||||||
return DerivePathType.bip49;
|
|
||||||
}
|
|
||||||
throw ArgumentError('Invalid version or Network mismatch');
|
throw ArgumentError('Invalid version or Network mismatch');
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -419,15 +411,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
addrType = isar_models.AddressType.p2pkh;
|
addrType = isar_models.AddressType.p2pkh;
|
||||||
addressString = bitbox.Address.toCashAddress(addressString);
|
addressString = bitbox.Address.toCashAddress(addressString);
|
||||||
break;
|
break;
|
||||||
case DerivePathType.bip49:
|
|
||||||
addressString = P2SH(
|
|
||||||
data: PaymentData(
|
|
||||||
redeem: P2WPKH(data: data, network: _network).data),
|
|
||||||
network: _network)
|
|
||||||
.data
|
|
||||||
.address!;
|
|
||||||
addrType = isar_models.AddressType.p2sh;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw Exception("DerivePathType $type not supported");
|
throw Exception("DerivePathType $type not supported");
|
||||||
}
|
}
|
||||||
|
@ -518,7 +501,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
|
|
||||||
final deriveTypes = [
|
final deriveTypes = [
|
||||||
DerivePathType.bip44,
|
DerivePathType.bip44,
|
||||||
DerivePathType.bip49,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (coin != Coin.bitcoincashTestnet) {
|
if (coin != Coin.bitcoincashTestnet) {
|
||||||
|
@ -1397,10 +1379,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
// P2PKH
|
// P2PKH
|
||||||
_generateAddressForChain(0, 0, DerivePathType.bip44),
|
_generateAddressForChain(0, 0, DerivePathType.bip44),
|
||||||
_generateAddressForChain(1, 0, DerivePathType.bip44),
|
_generateAddressForChain(1, 0, DerivePathType.bip44),
|
||||||
|
|
||||||
// P2SH
|
|
||||||
_generateAddressForChain(0, 0, DerivePathType.bip49),
|
|
||||||
_generateAddressForChain(1, 0, DerivePathType.bip49),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await db.putAddresses(initialAddresses);
|
await db.putAddresses(initialAddresses);
|
||||||
|
@ -1408,7 +1386,7 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info);
|
Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a new internal or external chain address for the wallet using a BIP44 or BIP49 derivation path.
|
/// Generates a new internal or external chain address for the wallet using a BIP44 derivation path.
|
||||||
/// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
|
/// [chain] - Use 0 for receiving (external), 1 for change (internal). Should not be any other value!
|
||||||
/// [index] - This can be any integer >= 0
|
/// [index] - This can be any integer >= 0
|
||||||
Future<isar_models.Address> _generateAddressForChain(
|
Future<isar_models.Address> _generateAddressForChain(
|
||||||
|
@ -1449,17 +1427,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
addrType = isar_models.AddressType.p2pkh;
|
addrType = isar_models.AddressType.p2pkh;
|
||||||
address = bitbox.Address.toCashAddress(address);
|
address = bitbox.Address.toCashAddress(address);
|
||||||
break;
|
break;
|
||||||
case DerivePathType.bip49:
|
|
||||||
address = P2SH(
|
|
||||||
data: PaymentData(
|
|
||||||
redeem: P2WPKH(data: data, network: _network).data),
|
|
||||||
network: _network)
|
|
||||||
.data
|
|
||||||
.address!;
|
|
||||||
addrType = isar_models.AddressType.p2sh;
|
|
||||||
break;
|
|
||||||
case DerivePathType.bip84:
|
|
||||||
throw UnsupportedError("bip84 not supported by BCH");
|
|
||||||
default:
|
default:
|
||||||
throw Exception("DerivePathType $derivePathType not supported");
|
throw Exception("DerivePathType $derivePathType not supported");
|
||||||
}
|
}
|
||||||
|
@ -1502,13 +1469,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
coinType = coin == Coin.bitcoincash ? "0" : "1";
|
coinType = coin == Coin.bitcoincash ? "0" : "1";
|
||||||
purpose = "44";
|
purpose = "44";
|
||||||
break;
|
break;
|
||||||
case DerivePathType.bip49:
|
|
||||||
type = isar_models.AddressType.p2sh;
|
|
||||||
coinType = coin == Coin.bitcoincash ? "145" : "1";
|
|
||||||
purpose = "49";
|
|
||||||
break;
|
|
||||||
case DerivePathType.bip84:
|
|
||||||
throw UnsupportedError("bip84 not supported by BCH");
|
|
||||||
default:
|
default:
|
||||||
throw Exception("DerivePathType $derivePathType not supported");
|
throw Exception("DerivePathType $derivePathType not supported");
|
||||||
}
|
}
|
||||||
|
@ -1537,9 +1497,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
case DerivePathType.bch44:
|
case DerivePathType.bch44:
|
||||||
key = "${walletId}_${chainId}DerivationsBch44P2PKH";
|
key = "${walletId}_${chainId}DerivationsBch44P2PKH";
|
||||||
break;
|
break;
|
||||||
case DerivePathType.bip49:
|
|
||||||
key = "${walletId}_${chainId}DerivationsP2SH";
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw UnsupportedError(
|
throw UnsupportedError(
|
||||||
"${derivePathType.name} not supported by ${coin.prettyName}");
|
"${derivePathType.name} not supported by ${coin.prettyName}");
|
||||||
|
@ -2721,20 +2678,6 @@ class BitcoinCashWallet extends CoinServiceAPI
|
||||||
redeemScript = null;
|
redeemScript = null;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DerivePathType.bip49:
|
|
||||||
final p2wpkh = P2WPKH(
|
|
||||||
data: PaymentData(
|
|
||||||
pubkey: Format.stringToUint8List(pubKey),
|
|
||||||
),
|
|
||||||
network: _network,
|
|
||||||
).data;
|
|
||||||
redeemScript = p2wpkh.output;
|
|
||||||
data = P2SH(
|
|
||||||
data: PaymentData(redeem: p2wpkh),
|
|
||||||
network: _network,
|
|
||||||
).data;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception("DerivePathType unsupported");
|
throw Exception("DerivePathType unsupported");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@ import 'package:stackwallet/services/event_bus/events/global/updated_in_backgrou
|
||||||
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
||||||
import 'package:stackwallet/services/mixins/coin_control_interface.dart';
|
import 'package:stackwallet/services/mixins/coin_control_interface.dart';
|
||||||
import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart';
|
import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart';
|
||||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
|
||||||
import 'package:stackwallet/services/mixins/xpubable.dart';
|
import 'package:stackwallet/services/mixins/xpubable.dart';
|
||||||
|
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
|
||||||
|
@ -252,7 +252,8 @@ class Manager with ChangeNotifier {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get hasXPub => _currentWallet is XPubAble;
|
// TODO: re enable once xpubs have been redone
|
||||||
|
bool get hasXPub => false; //_currentWallet is XPubAble;
|
||||||
|
|
||||||
Future<String> get xpub async {
|
Future<String> get xpub async {
|
||||||
if (!hasXPub) {
|
if (!hasXPub) {
|
||||||
|
|
|
@ -103,6 +103,7 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
// icons
|
// icons
|
||||||
final Color bottomNavIconBack;
|
final Color bottomNavIconBack;
|
||||||
final Color bottomNavIconIcon;
|
final Color bottomNavIconIcon;
|
||||||
|
final Color bottomNavIconIconHighlighted;
|
||||||
final Color topNavIconPrimary;
|
final Color topNavIconPrimary;
|
||||||
final Color topNavIconGreen;
|
final Color topNavIconGreen;
|
||||||
final Color topNavIconYellow;
|
final Color topNavIconYellow;
|
||||||
|
@ -281,6 +282,7 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
required this.snackBarTextInfo,
|
required this.snackBarTextInfo,
|
||||||
required this.bottomNavIconBack,
|
required this.bottomNavIconBack,
|
||||||
required this.bottomNavIconIcon,
|
required this.bottomNavIconIcon,
|
||||||
|
required this.bottomNavIconIconHighlighted,
|
||||||
required this.topNavIconPrimary,
|
required this.topNavIconPrimary,
|
||||||
required this.topNavIconGreen,
|
required this.topNavIconGreen,
|
||||||
required this.topNavIconYellow,
|
required this.topNavIconYellow,
|
||||||
|
@ -441,6 +443,7 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
snackBarTextInfo: colorTheme.snackBarTextInfo,
|
snackBarTextInfo: colorTheme.snackBarTextInfo,
|
||||||
bottomNavIconBack: colorTheme.bottomNavIconBack,
|
bottomNavIconBack: colorTheme.bottomNavIconBack,
|
||||||
bottomNavIconIcon: colorTheme.bottomNavIconIcon,
|
bottomNavIconIcon: colorTheme.bottomNavIconIcon,
|
||||||
|
bottomNavIconIconHighlighted: colorTheme.bottomNavIconIconHighlighted,
|
||||||
topNavIconPrimary: colorTheme.topNavIconPrimary,
|
topNavIconPrimary: colorTheme.topNavIconPrimary,
|
||||||
topNavIconGreen: colorTheme.topNavIconGreen,
|
topNavIconGreen: colorTheme.topNavIconGreen,
|
||||||
topNavIconYellow: colorTheme.topNavIconYellow,
|
topNavIconYellow: colorTheme.topNavIconYellow,
|
||||||
|
@ -603,6 +606,7 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
Color? snackBarTextInfo,
|
Color? snackBarTextInfo,
|
||||||
Color? bottomNavIconBack,
|
Color? bottomNavIconBack,
|
||||||
Color? bottomNavIconIcon,
|
Color? bottomNavIconIcon,
|
||||||
|
Color? bottomNavIconIconHighlighted,
|
||||||
Color? topNavIconPrimary,
|
Color? topNavIconPrimary,
|
||||||
Color? topNavIconGreen,
|
Color? topNavIconGreen,
|
||||||
Color? topNavIconYellow,
|
Color? topNavIconYellow,
|
||||||
|
@ -776,6 +780,8 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
snackBarTextInfo: snackBarTextInfo ?? this.snackBarTextInfo,
|
snackBarTextInfo: snackBarTextInfo ?? this.snackBarTextInfo,
|
||||||
bottomNavIconBack: bottomNavIconBack ?? this.bottomNavIconBack,
|
bottomNavIconBack: bottomNavIconBack ?? this.bottomNavIconBack,
|
||||||
bottomNavIconIcon: bottomNavIconIcon ?? this.bottomNavIconIcon,
|
bottomNavIconIcon: bottomNavIconIcon ?? this.bottomNavIconIcon,
|
||||||
|
bottomNavIconIconHighlighted:
|
||||||
|
bottomNavIconIconHighlighted ?? this.bottomNavIconIconHighlighted,
|
||||||
topNavIconPrimary: topNavIconPrimary ?? this.topNavIconPrimary,
|
topNavIconPrimary: topNavIconPrimary ?? this.topNavIconPrimary,
|
||||||
topNavIconGreen: topNavIconGreen ?? this.topNavIconGreen,
|
topNavIconGreen: topNavIconGreen ?? this.topNavIconGreen,
|
||||||
topNavIconYellow: topNavIconYellow ?? this.topNavIconYellow,
|
topNavIconYellow: topNavIconYellow ?? this.topNavIconYellow,
|
||||||
|
@ -1279,6 +1285,11 @@ class StackColors extends ThemeExtension<StackColors> {
|
||||||
other.bottomNavIconIcon,
|
other.bottomNavIconIcon,
|
||||||
t,
|
t,
|
||||||
)!,
|
)!,
|
||||||
|
bottomNavIconIconHighlighted: Color.lerp(
|
||||||
|
bottomNavIconIconHighlighted,
|
||||||
|
other.bottomNavIconIconHighlighted,
|
||||||
|
t,
|
||||||
|
)!,
|
||||||
topNavIconPrimary: Color.lerp(
|
topNavIconPrimary: Color.lerp(
|
||||||
topNavIconPrimary,
|
topNavIconPrimary,
|
||||||
other.topNavIconPrimary,
|
other.topNavIconPrimary,
|
||||||
|
|
|
@ -42,7 +42,7 @@ abstract class Constants {
|
||||||
// Enable Logger.print statements
|
// Enable Logger.print statements
|
||||||
static const bool disableLogger = false;
|
static const bool disableLogger = false;
|
||||||
|
|
||||||
static const int currentHiveDbVersion = 8;
|
static const int currentDataVersion = 10;
|
||||||
|
|
||||||
static const int rescanV1 = 1;
|
static const int rescanV1 = 1;
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,12 @@ import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
import 'package:stackwallet/db/hive/db.dart';
|
||||||
import 'package:stackwallet/db/isar/main_db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
|
import 'package:stackwallet/electrumx_rpc/electrumx.dart';
|
||||||
|
import 'package:stackwallet/models/contact.dart';
|
||||||
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
|
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
|
||||||
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
|
import 'package:stackwallet/models/exchange/response_objects/trade.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/contact_entry.dart'
|
||||||
|
as isar_contact;
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
|
||||||
import 'package:stackwallet/models/models.dart';
|
import 'package:stackwallet/models/models.dart';
|
||||||
import 'package:stackwallet/models/node_model.dart';
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
|
@ -290,6 +293,48 @@ class DbVersionMigrator with WalletDB {
|
||||||
// try to continue migrating
|
// try to continue migrating
|
||||||
return await migrate(8, secureStore: secureStore);
|
return await migrate(8, secureStore: secureStore);
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
// migrate
|
||||||
|
await Hive.openBox<dynamic>(DB.boxNameAllWalletsData);
|
||||||
|
final walletsService =
|
||||||
|
WalletsService(secureStorageInterface: secureStore);
|
||||||
|
final walletInfoList = await walletsService.walletNames;
|
||||||
|
await MainDB.instance.initMainDB();
|
||||||
|
for (final walletId in walletInfoList.keys) {
|
||||||
|
final info = walletInfoList[walletId]!;
|
||||||
|
if (info.coin == Coin.bitcoincash ||
|
||||||
|
info.coin == Coin.bitcoincashTestnet) {
|
||||||
|
final ids = await MainDB.instance
|
||||||
|
.getAddresses(walletId)
|
||||||
|
.filter()
|
||||||
|
.typeEqualTo(isar_models.AddressType.p2sh)
|
||||||
|
.idProperty()
|
||||||
|
.findAll();
|
||||||
|
|
||||||
|
await MainDB.instance.isar.writeTxn(() async {
|
||||||
|
await MainDB.instance.isar.addresses.deleteAll(ids);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update version
|
||||||
|
await DB.instance.put<dynamic>(
|
||||||
|
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 9);
|
||||||
|
|
||||||
|
// try to continue migrating
|
||||||
|
return await migrate(9, secureStore: secureStore);
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
// migrate
|
||||||
|
await _v9();
|
||||||
|
|
||||||
|
// update version
|
||||||
|
await DB.instance.put<dynamic>(
|
||||||
|
boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 10);
|
||||||
|
|
||||||
|
// try to continue migrating
|
||||||
|
return await migrate(10, secureStore: secureStore);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// finally return
|
// finally return
|
||||||
return;
|
return;
|
||||||
|
@ -447,4 +492,50 @@ class DbVersionMigrator with WalletDB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _v9() async {
|
||||||
|
final addressBookBox = await Hive.openBox<dynamic>(DB.boxNameAddressBook);
|
||||||
|
await MainDB.instance.initMainDB();
|
||||||
|
|
||||||
|
final keys = List<String>.from(addressBookBox.keys);
|
||||||
|
final contacts = keys
|
||||||
|
.map((id) => Contact.fromJson(
|
||||||
|
Map<String, dynamic>.from(
|
||||||
|
addressBookBox.get(id) as Map,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.toList(growable: false);
|
||||||
|
|
||||||
|
final List<isar_contact.ContactEntry> newContacts = [];
|
||||||
|
|
||||||
|
for (final contact in contacts) {
|
||||||
|
final List<isar_contact.ContactAddressEntry> newContactAddressEntries =
|
||||||
|
[];
|
||||||
|
|
||||||
|
for (final entry in contact.addresses) {
|
||||||
|
newContactAddressEntries.add(
|
||||||
|
isar_contact.ContactAddressEntry()
|
||||||
|
..coinName = entry.coin.name
|
||||||
|
..address = entry.address
|
||||||
|
..label = entry.label
|
||||||
|
..other = entry.other,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final newContact = isar_contact.ContactEntry(
|
||||||
|
name: contact.name,
|
||||||
|
addresses: newContactAddressEntries,
|
||||||
|
isFavorite: contact.isFavorite,
|
||||||
|
customId: contact.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
newContacts.add(newContact);
|
||||||
|
}
|
||||||
|
|
||||||
|
await MainDB.instance.isar.writeTxn(() async {
|
||||||
|
await MainDB.instance.isar.contactEntrys.putAll(newContacts);
|
||||||
|
});
|
||||||
|
|
||||||
|
await addressBookBox.deleteFromDisk();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/themes/theme_providers.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
@ -14,8 +17,6 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
import 'package:stackwallet/widgets/expandable.dart';
|
import 'package:stackwallet/widgets/expandable.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
import '../themes/theme_providers.dart';
|
|
||||||
|
|
||||||
class AddressBookCard extends ConsumerStatefulWidget {
|
class AddressBookCard extends ConsumerStatefulWidget {
|
||||||
const AddressBookCard({
|
const AddressBookCard({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -48,7 +49,7 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// provider hack to prevent trying to update widget with deleted contact
|
// provider hack to prevent trying to update widget with deleted contact
|
||||||
Contact? _contact;
|
ContactEntry? _contact;
|
||||||
try {
|
try {
|
||||||
_contact = ref.watch(addressBookServiceProvider
|
_contact = ref.watch(addressBookServiceProvider
|
||||||
.select((value) => value.getContactById(contactId)));
|
.select((value) => value.getContactById(contactId)));
|
||||||
|
@ -81,7 +82,7 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: contact.id == "default"
|
color: contact.customId == "default"
|
||||||
? Theme.of(context)
|
? Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.myStackContactIconBG
|
.myStackContactIconBG
|
||||||
|
@ -90,12 +91,14 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
|
||||||
.textFieldDefaultBG,
|
.textFieldDefaultBG,
|
||||||
borderRadius: BorderRadius.circular(32),
|
borderRadius: BorderRadius.circular(32),
|
||||||
),
|
),
|
||||||
child: contact.id == "default"
|
child: contact.customId == "default"
|
||||||
? Center(
|
? Center(
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.stackIcon,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
width: 20,
|
width: 20,
|
||||||
|
@ -176,7 +179,7 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
|
||||||
useSafeArea: true,
|
useSafeArea: true,
|
||||||
barrierDismissible: true,
|
barrierDismissible: true,
|
||||||
builder: (_) => ContactPopUp(
|
builder: (_) => ContactPopUp(
|
||||||
contactId: contact.id,
|
contactId: contact.customId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
@ -47,10 +49,12 @@ class _LivingStackIconState extends ConsumerState<LivingStackIcon> {
|
||||||
child: AnimatedScale(
|
child: AnimatedScale(
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
scale: _hovering ? 1.2 : 1,
|
scale: _hovering ? 1.2 : 1,
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.file(
|
||||||
ref.watch(
|
File(
|
||||||
themeProvider.select(
|
ref.watch(
|
||||||
(value) => value.assets.stackIcon,
|
themeProvider.select(
|
||||||
|
(value) => value.assets.stackIcon,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -46,6 +46,12 @@ class RoundedContainer extends StatelessWidget {
|
||||||
borderRadius: BorderRadius.circular(
|
borderRadius: BorderRadius.circular(
|
||||||
Constants.size.circularBorderRadius * radiusMultiplier,
|
Constants.size.circularBorderRadius * radiusMultiplier,
|
||||||
),
|
),
|
||||||
|
side: borderColor == null
|
||||||
|
? BorderSide.none
|
||||||
|
: BorderSide(
|
||||||
|
color: borderColor!,
|
||||||
|
width: 1.2,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: child,
|
child: child,
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ExchangeNavIcon extends ConsumerWidget {
|
||||||
File(
|
File(
|
||||||
ref.watch(
|
ref.watch(
|
||||||
themeProvider.select(
|
themeProvider.select(
|
||||||
(value) => value.assets.buy,
|
(value) => value.assets.exchange,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -68,9 +68,10 @@ class WalletNavigationBarItem extends ConsumerWidget {
|
||||||
Text(
|
Text(
|
||||||
data.label ?? "",
|
data.label ?? "",
|
||||||
style: STextStyles.buttonSmall(context).copyWith(
|
style: STextStyles.buttonSmall(context).copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.bottomNavText),
|
.bottomNavText,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -112,7 +113,11 @@ class WalletNavigationBarMoreItem extends ConsumerWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
data.label ?? "",
|
data.label ?? "",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: STextStyles.buttonSmall(context),
|
style: STextStyles.buttonSmall(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.bottomNavText,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
|
|
|
@ -175,7 +175,7 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> {
|
||||||
height: 20,
|
height: 20,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.infoItemIcons,
|
.bottomNavIconIconHighlighted,
|
||||||
),
|
),
|
||||||
crossFadeState: ref
|
crossFadeState: ref
|
||||||
.watch(walletNavBarMore.state)
|
.watch(walletNavBarMore.state)
|
||||||
|
@ -190,10 +190,10 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> {
|
||||||
style:
|
style:
|
||||||
STextStyles.buttonSmall(context)
|
STextStyles.buttonSmall(context)
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<
|
.extension<StackColors>()!
|
||||||
StackColors>()!
|
.bottomNavText,
|
||||||
.bottomNavText),
|
),
|
||||||
),
|
),
|
||||||
secondChild: Text(
|
secondChild: Text(
|
||||||
"More",
|
"More",
|
||||||
|
@ -202,7 +202,7 @@ class _WalletNavigationBarState extends ConsumerState<WalletNavigationBar> {
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.infoItemIcons,
|
.bottomNavIconIconHighlighted,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
crossFadeState: ref
|
crossFadeState: ref
|
||||||
|
|
|
@ -11,7 +11,7 @@ description: Stack Wallet
|
||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.7.8+170
|
version: 1.7.8+171
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.0 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
@ -343,14 +343,9 @@ flutter:
|
||||||
# exchange icons
|
# exchange icons
|
||||||
- assets/svg/exchange_icons/
|
- assets/svg/exchange_icons/
|
||||||
|
|
||||||
# theme selectors
|
|
||||||
# - assets/svg/dark-theme.svg
|
|
||||||
# - assets/svg/light-mode.svg
|
|
||||||
|
|
||||||
# buy
|
# buy
|
||||||
- assets/svg/buy/
|
- assets/svg/buy/
|
||||||
|
|
||||||
|
|
||||||
# lottie animations
|
# lottie animations
|
||||||
# basic
|
# basic
|
||||||
- assets/lottie/test2.json
|
- assets/lottie/test2.json
|
||||||
|
|
|
@ -1,174 +0,0 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
|
||||||
import 'package:hive_test/hive_test.dart';
|
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
|
||||||
import 'package:stackwallet/models/contact.dart';
|
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/services/address_book_service.dart';
|
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
group("Empty DB tests", () {
|
|
||||||
setUp(() async {
|
|
||||||
await setUpTestHive();
|
|
||||||
await Hive.openBox<dynamic>(DB.boxNameAddressBook);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("get empty contacts", () {
|
|
||||||
final service = AddressBookService();
|
|
||||||
expect(service.contacts, <Contact>[]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("get empty addressBookEntries", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
expect(await service.addressBookEntries, <Contact>[]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("getContactById from empty db", () {
|
|
||||||
final service = AddressBookService();
|
|
||||||
expect(() => service.getContactById("some id"), throwsException);
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() async {
|
|
||||||
await tearDownTestHive();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group("Preloaded DB tests", () {
|
|
||||||
final contactA = Contact(name: "john", addresses: [], isFavorite: true);
|
|
||||||
final contactB = Contact(
|
|
||||||
name: "JANE",
|
|
||||||
addresses: [
|
|
||||||
const ContactAddressEntry(
|
|
||||||
coin: Coin.bitcoin,
|
|
||||||
address: "some btc address",
|
|
||||||
label: "rent",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
isFavorite: false);
|
|
||||||
final contactC = Contact(
|
|
||||||
name: "Bill",
|
|
||||||
addresses: [
|
|
||||||
const ContactAddressEntry(
|
|
||||||
coin: Coin.monero,
|
|
||||||
address: "some xmr address",
|
|
||||||
label: "market",
|
|
||||||
),
|
|
||||||
const ContactAddressEntry(
|
|
||||||
coin: Coin.epicCash,
|
|
||||||
address: "some epic address",
|
|
||||||
label: "gas",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
isFavorite: true);
|
|
||||||
|
|
||||||
setUp(() async {
|
|
||||||
await setUpTestHive();
|
|
||||||
await Hive.openBox<dynamic>(DB.boxNameAddressBook);
|
|
||||||
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: DB.boxNameAddressBook,
|
|
||||||
key: contactA.id,
|
|
||||||
value: contactA.toMap());
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: DB.boxNameAddressBook,
|
|
||||||
key: contactB.id,
|
|
||||||
value: contactB.toMap());
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: DB.boxNameAddressBook,
|
|
||||||
key: contactC.id,
|
|
||||||
value: contactC.toMap());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("getContactById with non existing ID", () {
|
|
||||||
final service = AddressBookService();
|
|
||||||
expect(() => service.getContactById("some id"), throwsException);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("getContactById with existing ID", () {
|
|
||||||
final service = AddressBookService();
|
|
||||||
expect(
|
|
||||||
service.getContactById(contactA.id).toString(), contactA.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("get contacts", () {
|
|
||||||
final service = AddressBookService();
|
|
||||||
expect(service.contacts.toString(),
|
|
||||||
[contactC, contactB, contactA].toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("get addressBookEntries", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
expect((await service.addressBookEntries).toString(),
|
|
||||||
[contactC, contactB, contactA].toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("search contacts", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
final results = await service.search("j");
|
|
||||||
expect(results.toString(), [contactB, contactA].toString());
|
|
||||||
|
|
||||||
final results2 = await service.search("ja");
|
|
||||||
expect(results2.toString(), [contactB].toString());
|
|
||||||
|
|
||||||
final results3 = await service.search("john");
|
|
||||||
expect(results3.toString(), [contactA].toString());
|
|
||||||
|
|
||||||
final results4 = await service.search("po");
|
|
||||||
expect(results4.toString(), <Contact>[].toString());
|
|
||||||
|
|
||||||
final results5 = await service.search("");
|
|
||||||
expect(results5.toString(), [contactC, contactB, contactA].toString());
|
|
||||||
|
|
||||||
final results6 = await service.search("epic address");
|
|
||||||
expect(results6.toString(), [contactC].toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("add new contact", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
final contactD = Contact(name: "tim", addresses: [], isFavorite: true);
|
|
||||||
final result = await service.addContact(contactD);
|
|
||||||
expect(result, true);
|
|
||||||
expect(service.contacts.length, 4);
|
|
||||||
expect(
|
|
||||||
service.getContactById(contactD.id).toString(), contactD.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("add duplicate contact", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
final result = await service.addContact(contactA);
|
|
||||||
expect(result, false);
|
|
||||||
expect(service.contacts.length, 3);
|
|
||||||
expect(service.contacts.toString(),
|
|
||||||
[contactC, contactB, contactA].toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("edit contact", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
final editedContact = contactB.copyWith(name: "Mike");
|
|
||||||
expect(await service.editContact(editedContact), true);
|
|
||||||
expect(service.contacts.length, 3);
|
|
||||||
expect(service.contacts.toString(),
|
|
||||||
[contactC, contactA, editedContact].toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("remove existing contact", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
await service.removeContact(contactB.id);
|
|
||||||
expect(service.contacts.length, 2);
|
|
||||||
expect(service.contacts.toString(), [contactC, contactA].toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
test("remove non existing contact", () async {
|
|
||||||
final service = AddressBookService();
|
|
||||||
await service.removeContact("some id");
|
|
||||||
expect(service.contacts.length, 3);
|
|
||||||
expect(service.contacts.toString(),
|
|
||||||
[contactC, contactB, contactA].toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() async {
|
|
||||||
await tearDownTestHive();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,17 +1,35 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:mockito/annotations.dart';
|
||||||
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:stackwallet/models/isar/stack_theme.dart';
|
import 'package:stackwallet/models/isar/stack_theme.dart';
|
||||||
import 'package:stackwallet/models/notification_model.dart';
|
import 'package:stackwallet/models/notification_model.dart';
|
||||||
import 'package:stackwallet/notifications/notification_card.dart';
|
import 'package:stackwallet/notifications/notification_card.dart';
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/themes/theme_service.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
|
||||||
import '../sample_data/theme_json.dart';
|
import '../sample_data/theme_json.dart';
|
||||||
|
import 'notification_card_test.mocks.dart';
|
||||||
|
|
||||||
|
@GenerateMocks([
|
||||||
|
ThemeService,
|
||||||
|
])
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets("test notification card", (widgetTester) async {
|
testWidgets("test notification card", (widgetTester) async {
|
||||||
final key = UniqueKey();
|
final key = UniqueKey();
|
||||||
|
final mockThemeService = MockThemeService();
|
||||||
|
final theme = StackTheme.fromJson(
|
||||||
|
json: lightThemeJsonMap,
|
||||||
|
applicationThemesDirectoryPath: "test",
|
||||||
|
);
|
||||||
|
|
||||||
|
when(mockThemeService.getTheme(themeId: "light")).thenAnswer(
|
||||||
|
(_) => theme,
|
||||||
|
);
|
||||||
|
|
||||||
final notificationCard = NotificationCard(
|
final notificationCard = NotificationCard(
|
||||||
key: key,
|
key: key,
|
||||||
notification: NotificationModel(
|
notification: NotificationModel(
|
||||||
|
@ -27,19 +45,21 @@ void main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
await widgetTester.pumpWidget(
|
await widgetTester.pumpWidget(
|
||||||
MaterialApp(
|
ProviderScope(
|
||||||
theme: ThemeData(
|
overrides: [
|
||||||
extensions: [
|
pThemeService.overrideWithValue(mockThemeService),
|
||||||
StackColors.fromStackColorTheme(
|
],
|
||||||
StackTheme.fromJson(
|
child: MaterialApp(
|
||||||
json: lightThemeJsonMap,
|
theme: ThemeData(
|
||||||
applicationThemesDirectoryPath: "test",
|
extensions: [
|
||||||
|
StackColors.fromStackColorTheme(
|
||||||
|
theme,
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
home: Material(
|
||||||
home: Material(
|
child: notificationCard,
|
||||||
child: notificationCard,
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
122
test/notifications/notification_card_test.mocks.dart
Normal file
122
test/notifications/notification_card_test.mocks.dart
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
// Mocks generated by Mockito 5.3.2 from annotations
|
||||||
|
// in stackwallet/test/notifications/notification_card_test.dart.
|
||||||
|
// Do not manually edit this file.
|
||||||
|
|
||||||
|
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||||
|
import 'dart:async' as _i5;
|
||||||
|
import 'dart:typed_data' as _i6;
|
||||||
|
|
||||||
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
|
import 'package:stackwallet/db/isar/main_db.dart' as _i2;
|
||||||
|
import 'package:stackwallet/models/isar/stack_theme.dart' as _i4;
|
||||||
|
import 'package:stackwallet/themes/theme_service.dart' as _i3;
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: avoid_redundant_argument_values
|
||||||
|
// ignore_for_file: avoid_setters_without_getters
|
||||||
|
// ignore_for_file: comment_references
|
||||||
|
// ignore_for_file: implementation_imports
|
||||||
|
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||||
|
// ignore_for_file: prefer_const_constructors
|
||||||
|
// ignore_for_file: unnecessary_parenthesis
|
||||||
|
// ignore_for_file: camel_case_types
|
||||||
|
// ignore_for_file: subtype_of_sealed_class
|
||||||
|
|
||||||
|
class _FakeMainDB_0 extends _i1.SmartFake implements _i2.MainDB {
|
||||||
|
_FakeMainDB_0(
|
||||||
|
Object parent,
|
||||||
|
Invocation parentInvocation,
|
||||||
|
) : super(
|
||||||
|
parent,
|
||||||
|
parentInvocation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A class which mocks [ThemeService].
|
||||||
|
///
|
||||||
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
|
class MockThemeService extends _i1.Mock implements _i3.ThemeService {
|
||||||
|
MockThemeService() {
|
||||||
|
_i1.throwOnMissingStub(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_i2.MainDB get db => (super.noSuchMethod(
|
||||||
|
Invocation.getter(#db),
|
||||||
|
returnValue: _FakeMainDB_0(
|
||||||
|
this,
|
||||||
|
Invocation.getter(#db),
|
||||||
|
),
|
||||||
|
) as _i2.MainDB);
|
||||||
|
@override
|
||||||
|
List<_i4.StackTheme> get installedThemes => (super.noSuchMethod(
|
||||||
|
Invocation.getter(#installedThemes),
|
||||||
|
returnValue: <_i4.StackTheme>[],
|
||||||
|
) as List<_i4.StackTheme>);
|
||||||
|
@override
|
||||||
|
void init(_i2.MainDB? db) => super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#init,
|
||||||
|
[db],
|
||||||
|
),
|
||||||
|
returnValueForMissingStub: null,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
_i5.Future<void> install({required _i6.Uint8List? themeArchiveData}) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#install,
|
||||||
|
[],
|
||||||
|
{#themeArchiveData: themeArchiveData},
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
|
) as _i5.Future<void>);
|
||||||
|
@override
|
||||||
|
_i5.Future<void> remove({required String? themeId}) => (super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#remove,
|
||||||
|
[],
|
||||||
|
{#themeId: themeId},
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<void>.value(),
|
||||||
|
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||||
|
) as _i5.Future<void>);
|
||||||
|
@override
|
||||||
|
_i5.Future<bool> verifyInstalled({required String? themeId}) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#verifyInstalled,
|
||||||
|
[],
|
||||||
|
{#themeId: themeId},
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<bool>.value(false),
|
||||||
|
) as _i5.Future<bool>);
|
||||||
|
@override
|
||||||
|
_i5.Future<List<_i3.StackThemeMetaData>> fetchThemes() => (super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#fetchThemes,
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<List<_i3.StackThemeMetaData>>.value(
|
||||||
|
<_i3.StackThemeMetaData>[]),
|
||||||
|
) as _i5.Future<List<_i3.StackThemeMetaData>>);
|
||||||
|
@override
|
||||||
|
_i5.Future<_i6.Uint8List> fetchTheme(
|
||||||
|
{required _i3.StackThemeMetaData? themeMetaData}) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#fetchTheme,
|
||||||
|
[],
|
||||||
|
{#themeMetaData: themeMetaData},
|
||||||
|
),
|
||||||
|
returnValue: _i5.Future<_i6.Uint8List>.value(_i6.Uint8List(0)),
|
||||||
|
) as _i5.Future<_i6.Uint8List>);
|
||||||
|
@override
|
||||||
|
_i4.StackTheme? getTheme({required String? themeId}) =>
|
||||||
|
(super.noSuchMethod(Invocation.method(
|
||||||
|
#getTheme,
|
||||||
|
[],
|
||||||
|
{#themeId: themeId},
|
||||||
|
)) as _i4.StackTheme?);
|
||||||
|
}
|
|
@ -91,6 +91,7 @@ const Map<String, dynamic> lightThemeJsonMap = {
|
||||||
"snack_bar_text_info": "0xFF002A78",
|
"snack_bar_text_info": "0xFF002A78",
|
||||||
"bottom_nav_icon_back": "0xFFA2A2A2",
|
"bottom_nav_icon_back": "0xFFA2A2A2",
|
||||||
"bottom_nav_icon_icon": "0xFF232323",
|
"bottom_nav_icon_icon": "0xFF232323",
|
||||||
|
"bottom_nav_icon_icon_highlighted": "0xFF232323",
|
||||||
"top_nav_icon_primary": "0xFF232323",
|
"top_nav_icon_primary": "0xFF232323",
|
||||||
"top_nav_icon_green": "0xFF00A578",
|
"top_nav_icon_green": "0xFF00A578",
|
||||||
"top_nav_icon_yellow": "0xFFF4C517",
|
"top_nav_icon_yellow": "0xFFF4C517",
|
||||||
|
|
|
@ -7,7 +7,7 @@ import 'dart:async' as _i4;
|
||||||
import 'dart:ui' as _i5;
|
import 'dart:ui' as _i5;
|
||||||
|
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/models/contact.dart' as _i2;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i2;
|
||||||
import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
|
@ -21,8 +21,8 @@ import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
||||||
// ignore_for_file: camel_case_types
|
// ignore_for_file: camel_case_types
|
||||||
// ignore_for_file: subtype_of_sealed_class
|
// ignore_for_file: subtype_of_sealed_class
|
||||||
|
|
||||||
class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
class _FakeContactEntry_0 extends _i1.SmartFake implements _i2.ContactEntry {
|
||||||
_FakeContact_0(
|
_FakeContactEntry_0(
|
||||||
Object parent,
|
Object parent,
|
||||||
Invocation parentInvocation,
|
Invocation parentInvocation,
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -37,46 +37,43 @@ class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
||||||
class MockAddressBookService extends _i1.Mock
|
class MockAddressBookService extends _i1.Mock
|
||||||
implements _i3.AddressBookService {
|
implements _i3.AddressBookService {
|
||||||
@override
|
@override
|
||||||
List<_i2.Contact> get contacts => (super.noSuchMethod(
|
List<_i2.ContactEntry> get contacts => (super.noSuchMethod(
|
||||||
Invocation.getter(#contacts),
|
Invocation.getter(#contacts),
|
||||||
returnValue: <_i2.Contact>[],
|
returnValue: <_i2.ContactEntry>[],
|
||||||
) as List<_i2.Contact>);
|
) as List<_i2.ContactEntry>);
|
||||||
@override
|
|
||||||
_i4.Future<List<_i2.Contact>> get addressBookEntries => (super.noSuchMethod(
|
|
||||||
Invocation.getter(#addressBookEntries),
|
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
|
||||||
@override
|
@override
|
||||||
bool get hasListeners => (super.noSuchMethod(
|
bool get hasListeners => (super.noSuchMethod(
|
||||||
Invocation.getter(#hasListeners),
|
Invocation.getter(#hasListeners),
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i2.Contact getContactById(String? id) => (super.noSuchMethod(
|
_i2.ContactEntry getContactById(String? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _FakeContact_0(
|
returnValue: _FakeContactEntry_0(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i2.Contact);
|
) as _i2.ContactEntry);
|
||||||
@override
|
@override
|
||||||
_i4.Future<List<_i2.Contact>> search(String? text) => (super.noSuchMethod(
|
_i4.Future<List<_i2.ContactEntry>> search(String? text) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#search,
|
#search,
|
||||||
[text],
|
[text],
|
||||||
),
|
),
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
returnValue:
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
_i4.Future<List<_i2.ContactEntry>>.value(<_i2.ContactEntry>[]),
|
||||||
|
) as _i4.Future<List<_i2.ContactEntry>>);
|
||||||
@override
|
@override
|
||||||
bool matches(
|
bool matches(
|
||||||
String? term,
|
String? term,
|
||||||
_i2.Contact? contact,
|
_i2.ContactEntry? contact,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -89,7 +86,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> addContact(_i2.Contact? contact) => (super.noSuchMethod(
|
_i4.Future<bool> addContact(_i2.ContactEntry? contact) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#addContact,
|
#addContact,
|
||||||
[contact],
|
[contact],
|
||||||
|
@ -97,7 +94,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: _i4.Future<bool>.value(false),
|
returnValue: _i4.Future<bool>.value(false),
|
||||||
) as _i4.Future<bool>);
|
) as _i4.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> editContact(_i2.Contact? editedContact) =>
|
_i4.Future<bool> editContact(_i2.ContactEntry? editedContact) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#editContact,
|
#editContact,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import 'dart:ui' as _i11;
|
||||||
import 'package:barcode_scan2/barcode_scan2.dart' as _i2;
|
import 'package:barcode_scan2/barcode_scan2.dart' as _i2;
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/models/balance.dart' as _i6;
|
import 'package:stackwallet/models/balance.dart' as _i6;
|
||||||
import 'package:stackwallet/models/contact.dart' as _i3;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i3;
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i14;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i14;
|
||||||
import 'package:stackwallet/models/models.dart' as _i5;
|
import 'package:stackwallet/models/models.dart' as _i5;
|
||||||
import 'package:stackwallet/services/address_book_service.dart' as _i10;
|
import 'package:stackwallet/services/address_book_service.dart' as _i10;
|
||||||
|
@ -40,8 +40,8 @@ class _FakeScanResult_0 extends _i1.SmartFake implements _i2.ScanResult {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FakeContact_1 extends _i1.SmartFake implements _i3.Contact {
|
class _FakeContactEntry_1 extends _i1.SmartFake implements _i3.ContactEntry {
|
||||||
_FakeContact_1(
|
_FakeContactEntry_1(
|
||||||
Object parent,
|
Object parent,
|
||||||
Invocation parentInvocation,
|
Invocation parentInvocation,
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -126,46 +126,43 @@ class MockBarcodeScannerWrapper extends _i1.Mock
|
||||||
class MockAddressBookService extends _i1.Mock
|
class MockAddressBookService extends _i1.Mock
|
||||||
implements _i10.AddressBookService {
|
implements _i10.AddressBookService {
|
||||||
@override
|
@override
|
||||||
List<_i3.Contact> get contacts => (super.noSuchMethod(
|
List<_i3.ContactEntry> get contacts => (super.noSuchMethod(
|
||||||
Invocation.getter(#contacts),
|
Invocation.getter(#contacts),
|
||||||
returnValue: <_i3.Contact>[],
|
returnValue: <_i3.ContactEntry>[],
|
||||||
) as List<_i3.Contact>);
|
) as List<_i3.ContactEntry>);
|
||||||
@override
|
|
||||||
_i9.Future<List<_i3.Contact>> get addressBookEntries => (super.noSuchMethod(
|
|
||||||
Invocation.getter(#addressBookEntries),
|
|
||||||
returnValue: _i9.Future<List<_i3.Contact>>.value(<_i3.Contact>[]),
|
|
||||||
) as _i9.Future<List<_i3.Contact>>);
|
|
||||||
@override
|
@override
|
||||||
bool get hasListeners => (super.noSuchMethod(
|
bool get hasListeners => (super.noSuchMethod(
|
||||||
Invocation.getter(#hasListeners),
|
Invocation.getter(#hasListeners),
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i3.Contact getContactById(String? id) => (super.noSuchMethod(
|
_i3.ContactEntry getContactById(String? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _FakeContact_1(
|
returnValue: _FakeContactEntry_1(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i3.Contact);
|
) as _i3.ContactEntry);
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i3.Contact>> search(String? text) => (super.noSuchMethod(
|
_i9.Future<List<_i3.ContactEntry>> search(String? text) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#search,
|
#search,
|
||||||
[text],
|
[text],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i3.Contact>>.value(<_i3.Contact>[]),
|
returnValue:
|
||||||
) as _i9.Future<List<_i3.Contact>>);
|
_i9.Future<List<_i3.ContactEntry>>.value(<_i3.ContactEntry>[]),
|
||||||
|
) as _i9.Future<List<_i3.ContactEntry>>);
|
||||||
@override
|
@override
|
||||||
bool matches(
|
bool matches(
|
||||||
String? term,
|
String? term,
|
||||||
_i3.Contact? contact,
|
_i3.ContactEntry? contact,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -178,7 +175,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i9.Future<bool> addContact(_i3.Contact? contact) => (super.noSuchMethod(
|
_i9.Future<bool> addContact(_i3.ContactEntry? contact) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#addContact,
|
#addContact,
|
||||||
[contact],
|
[contact],
|
||||||
|
@ -186,7 +183,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: _i9.Future<bool>.value(false),
|
returnValue: _i9.Future<bool>.value(false),
|
||||||
) as _i9.Future<bool>);
|
) as _i9.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i9.Future<bool> editContact(_i3.Contact? editedContact) =>
|
_i9.Future<bool> editContact(_i3.ContactEntry? editedContact) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#editContact,
|
#editContact,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'dart:ui' as _i9;
|
||||||
|
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/models/balance.dart' as _i5;
|
import 'package:stackwallet/models/balance.dart' as _i5;
|
||||||
import 'package:stackwallet/models/contact.dart' as _i2;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i2;
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i12;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i12;
|
||||||
import 'package:stackwallet/models/models.dart' as _i4;
|
import 'package:stackwallet/models/models.dart' as _i4;
|
||||||
import 'package:stackwallet/services/address_book_service.dart' as _i7;
|
import 'package:stackwallet/services/address_book_service.dart' as _i7;
|
||||||
|
@ -30,8 +30,8 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i11;
|
||||||
// ignore_for_file: camel_case_types
|
// ignore_for_file: camel_case_types
|
||||||
// ignore_for_file: subtype_of_sealed_class
|
// ignore_for_file: subtype_of_sealed_class
|
||||||
|
|
||||||
class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
class _FakeContactEntry_0 extends _i1.SmartFake implements _i2.ContactEntry {
|
||||||
_FakeContact_0(
|
_FakeContactEntry_0(
|
||||||
Object parent,
|
Object parent,
|
||||||
Invocation parentInvocation,
|
Invocation parentInvocation,
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -87,46 +87,43 @@ class _FakeAmount_4 extends _i1.SmartFake implements _i6.Amount {
|
||||||
class MockAddressBookService extends _i1.Mock
|
class MockAddressBookService extends _i1.Mock
|
||||||
implements _i7.AddressBookService {
|
implements _i7.AddressBookService {
|
||||||
@override
|
@override
|
||||||
List<_i2.Contact> get contacts => (super.noSuchMethod(
|
List<_i2.ContactEntry> get contacts => (super.noSuchMethod(
|
||||||
Invocation.getter(#contacts),
|
Invocation.getter(#contacts),
|
||||||
returnValue: <_i2.Contact>[],
|
returnValue: <_i2.ContactEntry>[],
|
||||||
) as List<_i2.Contact>);
|
) as List<_i2.ContactEntry>);
|
||||||
@override
|
|
||||||
_i8.Future<List<_i2.Contact>> get addressBookEntries => (super.noSuchMethod(
|
|
||||||
Invocation.getter(#addressBookEntries),
|
|
||||||
returnValue: _i8.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
|
||||||
) as _i8.Future<List<_i2.Contact>>);
|
|
||||||
@override
|
@override
|
||||||
bool get hasListeners => (super.noSuchMethod(
|
bool get hasListeners => (super.noSuchMethod(
|
||||||
Invocation.getter(#hasListeners),
|
Invocation.getter(#hasListeners),
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i2.Contact getContactById(String? id) => (super.noSuchMethod(
|
_i2.ContactEntry getContactById(String? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _FakeContact_0(
|
returnValue: _FakeContactEntry_0(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i2.Contact);
|
) as _i2.ContactEntry);
|
||||||
@override
|
@override
|
||||||
_i8.Future<List<_i2.Contact>> search(String? text) => (super.noSuchMethod(
|
_i8.Future<List<_i2.ContactEntry>> search(String? text) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#search,
|
#search,
|
||||||
[text],
|
[text],
|
||||||
),
|
),
|
||||||
returnValue: _i8.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
returnValue:
|
||||||
) as _i8.Future<List<_i2.Contact>>);
|
_i8.Future<List<_i2.ContactEntry>>.value(<_i2.ContactEntry>[]),
|
||||||
|
) as _i8.Future<List<_i2.ContactEntry>>);
|
||||||
@override
|
@override
|
||||||
bool matches(
|
bool matches(
|
||||||
String? term,
|
String? term,
|
||||||
_i2.Contact? contact,
|
_i2.ContactEntry? contact,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -139,7 +136,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i8.Future<bool> addContact(_i2.Contact? contact) => (super.noSuchMethod(
|
_i8.Future<bool> addContact(_i2.ContactEntry? contact) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#addContact,
|
#addContact,
|
||||||
[contact],
|
[contact],
|
||||||
|
@ -147,7 +144,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: _i8.Future<bool>.value(false),
|
returnValue: _i8.Future<bool>.value(false),
|
||||||
) as _i8.Future<bool>);
|
) as _i8.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i8.Future<bool> editContact(_i2.Contact? editedContact) =>
|
_i8.Future<bool> editContact(_i2.ContactEntry? editedContact) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#editContact,
|
#editContact,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'dart:ui' as _i9;
|
||||||
|
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/models/balance.dart' as _i5;
|
import 'package:stackwallet/models/balance.dart' as _i5;
|
||||||
import 'package:stackwallet/models/contact.dart' as _i2;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i2;
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i12;
|
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i12;
|
||||||
import 'package:stackwallet/models/models.dart' as _i4;
|
import 'package:stackwallet/models/models.dart' as _i4;
|
||||||
import 'package:stackwallet/services/address_book_service.dart' as _i7;
|
import 'package:stackwallet/services/address_book_service.dart' as _i7;
|
||||||
|
@ -28,8 +28,8 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i11;
|
||||||
// ignore_for_file: camel_case_types
|
// ignore_for_file: camel_case_types
|
||||||
// ignore_for_file: subtype_of_sealed_class
|
// ignore_for_file: subtype_of_sealed_class
|
||||||
|
|
||||||
class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
class _FakeContactEntry_0 extends _i1.SmartFake implements _i2.ContactEntry {
|
||||||
_FakeContact_0(
|
_FakeContactEntry_0(
|
||||||
Object parent,
|
Object parent,
|
||||||
Invocation parentInvocation,
|
Invocation parentInvocation,
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -85,46 +85,43 @@ class _FakeAmount_4 extends _i1.SmartFake implements _i6.Amount {
|
||||||
class MockAddressBookService extends _i1.Mock
|
class MockAddressBookService extends _i1.Mock
|
||||||
implements _i7.AddressBookService {
|
implements _i7.AddressBookService {
|
||||||
@override
|
@override
|
||||||
List<_i2.Contact> get contacts => (super.noSuchMethod(
|
List<_i2.ContactEntry> get contacts => (super.noSuchMethod(
|
||||||
Invocation.getter(#contacts),
|
Invocation.getter(#contacts),
|
||||||
returnValue: <_i2.Contact>[],
|
returnValue: <_i2.ContactEntry>[],
|
||||||
) as List<_i2.Contact>);
|
) as List<_i2.ContactEntry>);
|
||||||
@override
|
|
||||||
_i8.Future<List<_i2.Contact>> get addressBookEntries => (super.noSuchMethod(
|
|
||||||
Invocation.getter(#addressBookEntries),
|
|
||||||
returnValue: _i8.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
|
||||||
) as _i8.Future<List<_i2.Contact>>);
|
|
||||||
@override
|
@override
|
||||||
bool get hasListeners => (super.noSuchMethod(
|
bool get hasListeners => (super.noSuchMethod(
|
||||||
Invocation.getter(#hasListeners),
|
Invocation.getter(#hasListeners),
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i2.Contact getContactById(String? id) => (super.noSuchMethod(
|
_i2.ContactEntry getContactById(String? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _FakeContact_0(
|
returnValue: _FakeContactEntry_0(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i2.Contact);
|
) as _i2.ContactEntry);
|
||||||
@override
|
@override
|
||||||
_i8.Future<List<_i2.Contact>> search(String? text) => (super.noSuchMethod(
|
_i8.Future<List<_i2.ContactEntry>> search(String? text) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#search,
|
#search,
|
||||||
[text],
|
[text],
|
||||||
),
|
),
|
||||||
returnValue: _i8.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
returnValue:
|
||||||
) as _i8.Future<List<_i2.Contact>>);
|
_i8.Future<List<_i2.ContactEntry>>.value(<_i2.ContactEntry>[]),
|
||||||
|
) as _i8.Future<List<_i2.ContactEntry>>);
|
||||||
@override
|
@override
|
||||||
bool matches(
|
bool matches(
|
||||||
String? term,
|
String? term,
|
||||||
_i2.Contact? contact,
|
_i2.ContactEntry? contact,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -137,7 +134,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i8.Future<bool> addContact(_i2.Contact? contact) => (super.noSuchMethod(
|
_i8.Future<bool> addContact(_i2.ContactEntry? contact) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#addContact,
|
#addContact,
|
||||||
[contact],
|
[contact],
|
||||||
|
@ -145,7 +142,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: _i8.Future<bool>.value(false),
|
returnValue: _i8.Future<bool>.value(false),
|
||||||
) as _i8.Future<bool>);
|
) as _i8.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i8.Future<bool> editContact(_i2.Contact? editedContact) =>
|
_i8.Future<bool> editContact(_i2.ContactEntry? editedContact) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#editContact,
|
#editContact,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import 'dart:async' as _i4;
|
||||||
import 'dart:ui' as _i5;
|
import 'dart:ui' as _i5;
|
||||||
|
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/models/contact.dart' as _i2;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i2;
|
||||||
import 'package:stackwallet/services/address_book_service.dart' as _i6;
|
import 'package:stackwallet/services/address_book_service.dart' as _i6;
|
||||||
import 'package:stackwallet/services/locale_service.dart' as _i7;
|
import 'package:stackwallet/services/locale_service.dart' as _i7;
|
||||||
import 'package:stackwallet/services/notes_service.dart' as _i3;
|
import 'package:stackwallet/services/notes_service.dart' as _i3;
|
||||||
|
@ -23,8 +23,8 @@ import 'package:stackwallet/services/notes_service.dart' as _i3;
|
||||||
// ignore_for_file: camel_case_types
|
// ignore_for_file: camel_case_types
|
||||||
// ignore_for_file: subtype_of_sealed_class
|
// ignore_for_file: subtype_of_sealed_class
|
||||||
|
|
||||||
class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
class _FakeContactEntry_0 extends _i1.SmartFake implements _i2.ContactEntry {
|
||||||
_FakeContact_0(
|
_FakeContactEntry_0(
|
||||||
Object parent,
|
Object parent,
|
||||||
Invocation parentInvocation,
|
Invocation parentInvocation,
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -141,46 +141,43 @@ class MockNotesService extends _i1.Mock implements _i3.NotesService {
|
||||||
class MockAddressBookService extends _i1.Mock
|
class MockAddressBookService extends _i1.Mock
|
||||||
implements _i6.AddressBookService {
|
implements _i6.AddressBookService {
|
||||||
@override
|
@override
|
||||||
List<_i2.Contact> get contacts => (super.noSuchMethod(
|
List<_i2.ContactEntry> get contacts => (super.noSuchMethod(
|
||||||
Invocation.getter(#contacts),
|
Invocation.getter(#contacts),
|
||||||
returnValue: <_i2.Contact>[],
|
returnValue: <_i2.ContactEntry>[],
|
||||||
) as List<_i2.Contact>);
|
) as List<_i2.ContactEntry>);
|
||||||
@override
|
|
||||||
_i4.Future<List<_i2.Contact>> get addressBookEntries => (super.noSuchMethod(
|
|
||||||
Invocation.getter(#addressBookEntries),
|
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
|
||||||
@override
|
@override
|
||||||
bool get hasListeners => (super.noSuchMethod(
|
bool get hasListeners => (super.noSuchMethod(
|
||||||
Invocation.getter(#hasListeners),
|
Invocation.getter(#hasListeners),
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i2.Contact getContactById(String? id) => (super.noSuchMethod(
|
_i2.ContactEntry getContactById(String? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _FakeContact_0(
|
returnValue: _FakeContactEntry_0(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i2.Contact);
|
) as _i2.ContactEntry);
|
||||||
@override
|
@override
|
||||||
_i4.Future<List<_i2.Contact>> search(String? text) => (super.noSuchMethod(
|
_i4.Future<List<_i2.ContactEntry>> search(String? text) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#search,
|
#search,
|
||||||
[text],
|
[text],
|
||||||
),
|
),
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
returnValue:
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
_i4.Future<List<_i2.ContactEntry>>.value(<_i2.ContactEntry>[]),
|
||||||
|
) as _i4.Future<List<_i2.ContactEntry>>);
|
||||||
@override
|
@override
|
||||||
bool matches(
|
bool matches(
|
||||||
String? term,
|
String? term,
|
||||||
_i2.Contact? contact,
|
_i2.ContactEntry? contact,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -193,7 +190,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> addContact(_i2.Contact? contact) => (super.noSuchMethod(
|
_i4.Future<bool> addContact(_i2.ContactEntry? contact) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#addContact,
|
#addContact,
|
||||||
[contact],
|
[contact],
|
||||||
|
@ -201,7 +198,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: _i4.Future<bool>.value(false),
|
returnValue: _i4.Future<bool>.value(false),
|
||||||
) as _i4.Future<bool>);
|
) as _i4.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> editContact(_i2.Contact? editedContact) =>
|
_i4.Future<bool> editContact(_i2.ContactEntry? editedContact) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#editContact,
|
#editContact,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import 'dart:async' as _i4;
|
||||||
import 'dart:ui' as _i5;
|
import 'dart:ui' as _i5;
|
||||||
|
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/models/contact.dart' as _i2;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i2;
|
||||||
import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
||||||
import 'package:stackwallet/services/notes_service.dart' as _i6;
|
import 'package:stackwallet/services/notes_service.dart' as _i6;
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ import 'package:stackwallet/services/notes_service.dart' as _i6;
|
||||||
// ignore_for_file: camel_case_types
|
// ignore_for_file: camel_case_types
|
||||||
// ignore_for_file: subtype_of_sealed_class
|
// ignore_for_file: subtype_of_sealed_class
|
||||||
|
|
||||||
class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
class _FakeContactEntry_0 extends _i1.SmartFake implements _i2.ContactEntry {
|
||||||
_FakeContact_0(
|
_FakeContactEntry_0(
|
||||||
Object parent,
|
Object parent,
|
||||||
Invocation parentInvocation,
|
Invocation parentInvocation,
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -38,46 +38,43 @@ class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
||||||
class MockAddressBookService extends _i1.Mock
|
class MockAddressBookService extends _i1.Mock
|
||||||
implements _i3.AddressBookService {
|
implements _i3.AddressBookService {
|
||||||
@override
|
@override
|
||||||
List<_i2.Contact> get contacts => (super.noSuchMethod(
|
List<_i2.ContactEntry> get contacts => (super.noSuchMethod(
|
||||||
Invocation.getter(#contacts),
|
Invocation.getter(#contacts),
|
||||||
returnValue: <_i2.Contact>[],
|
returnValue: <_i2.ContactEntry>[],
|
||||||
) as List<_i2.Contact>);
|
) as List<_i2.ContactEntry>);
|
||||||
@override
|
|
||||||
_i4.Future<List<_i2.Contact>> get addressBookEntries => (super.noSuchMethod(
|
|
||||||
Invocation.getter(#addressBookEntries),
|
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
|
||||||
@override
|
@override
|
||||||
bool get hasListeners => (super.noSuchMethod(
|
bool get hasListeners => (super.noSuchMethod(
|
||||||
Invocation.getter(#hasListeners),
|
Invocation.getter(#hasListeners),
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i2.Contact getContactById(String? id) => (super.noSuchMethod(
|
_i2.ContactEntry getContactById(String? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _FakeContact_0(
|
returnValue: _FakeContactEntry_0(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i2.Contact);
|
) as _i2.ContactEntry);
|
||||||
@override
|
@override
|
||||||
_i4.Future<List<_i2.Contact>> search(String? text) => (super.noSuchMethod(
|
_i4.Future<List<_i2.ContactEntry>> search(String? text) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#search,
|
#search,
|
||||||
[text],
|
[text],
|
||||||
),
|
),
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
returnValue:
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
_i4.Future<List<_i2.ContactEntry>>.value(<_i2.ContactEntry>[]),
|
||||||
|
) as _i4.Future<List<_i2.ContactEntry>>);
|
||||||
@override
|
@override
|
||||||
bool matches(
|
bool matches(
|
||||||
String? term,
|
String? term,
|
||||||
_i2.Contact? contact,
|
_i2.ContactEntry? contact,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -90,7 +87,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> addContact(_i2.Contact? contact) => (super.noSuchMethod(
|
_i4.Future<bool> addContact(_i2.ContactEntry? contact) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#addContact,
|
#addContact,
|
||||||
[contact],
|
[contact],
|
||||||
|
@ -98,7 +95,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: _i4.Future<bool>.value(false),
|
returnValue: _i4.Future<bool>.value(false),
|
||||||
) as _i4.Future<bool>);
|
) as _i4.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> editContact(_i2.Contact? editedContact) =>
|
_i4.Future<bool> editContact(_i2.ContactEntry? editedContact) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#editContact,
|
#editContact,
|
||||||
|
|
|
@ -175,17 +175,6 @@ void main() async {
|
||||||
verifyNoMoreInteractions(cachedClient);
|
verifyNoMoreInteractions(cachedClient);
|
||||||
verifyNoMoreInteractions(tracker);
|
verifyNoMoreInteractions(tracker);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Multisig/P2SH address", () {
|
|
||||||
expect(
|
|
||||||
mainnetWallet?.addressType(
|
|
||||||
address: "3DYuVEmuKWQFxJcF7jDPhwPiXLTiNnyMFb"),
|
|
||||||
DerivePathType.bip49);
|
|
||||||
expect(secureStore.interactions, 0);
|
|
||||||
verifyNoMoreInteractions(client);
|
|
||||||
verifyNoMoreInteractions(cachedClient);
|
|
||||||
verifyNoMoreInteractions(tracker);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group("validate mainnet bitcoincash addresses", () {
|
group("validate mainnet bitcoincash addresses", () {
|
||||||
|
|
|
@ -5,18 +5,17 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mockito/annotations.dart';
|
import 'package:mockito/annotations.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:stackwallet/models/contact.dart';
|
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||||
import 'package:stackwallet/models/contact_address_entry.dart';
|
|
||||||
import 'package:stackwallet/models/isar/stack_theme.dart';
|
import 'package:stackwallet/models/isar/stack_theme.dart';
|
||||||
import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
|
import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
|
||||||
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
|
||||||
import 'package:stackwallet/services/address_book_service.dart';
|
import 'package:stackwallet/services/address_book_service.dart';
|
||||||
import '../sample_data/theme_json.dart';
|
|
||||||
import 'package:stackwallet/themes/stack_colors.dart';
|
import 'package:stackwallet/themes/stack_colors.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
import 'package:stackwallet/utilities/util.dart';
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
import 'package:stackwallet/widgets/address_book_card.dart';
|
import 'package:stackwallet/widgets/address_book_card.dart';
|
||||||
|
|
||||||
|
import '../sample_data/theme_json.dart';
|
||||||
import 'address_book_card_test.mocks.dart';
|
import 'address_book_card_test.mocks.dart';
|
||||||
|
|
||||||
class MockedFunctions extends Mock {
|
class MockedFunctions extends Mock {
|
||||||
|
@ -27,18 +26,20 @@ class MockedFunctions extends Mock {
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('test returns Contact Address Entry', (widgetTester) async {
|
testWidgets('test returns Contact Address Entry', (widgetTester) async {
|
||||||
final service = MockAddressBookService();
|
final service = MockAddressBookService();
|
||||||
final applicationThemesDirectoryPath = "";
|
const applicationThemesDirectoryPath = "";
|
||||||
|
|
||||||
when(service.getContactById("default")).thenAnswer(
|
when(service.getContactById("default")).thenAnswer(
|
||||||
(realInvocation) => Contact(
|
(realInvocation) => ContactEntry(
|
||||||
name: "John Doe",
|
name: "John Doe",
|
||||||
addresses: [
|
addresses: [
|
||||||
const ContactAddressEntry(
|
ContactAddressEntry()
|
||||||
coin: Coin.bitcoincash,
|
..coinName = Coin.bitcoincash.name
|
||||||
address: "some bch address",
|
..address = "some bch address"
|
||||||
label: "Bills")
|
..label = "Bills"
|
||||||
|
..other = null
|
||||||
],
|
],
|
||||||
isFavorite: true,
|
isFavorite: true,
|
||||||
|
customId: '',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import 'dart:async' as _i4;
|
||||||
import 'dart:ui' as _i5;
|
import 'dart:ui' as _i5;
|
||||||
|
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:stackwallet/models/contact.dart' as _i2;
|
import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i2;
|
||||||
import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
|
@ -21,8 +21,8 @@ import 'package:stackwallet/services/address_book_service.dart' as _i3;
|
||||||
// ignore_for_file: camel_case_types
|
// ignore_for_file: camel_case_types
|
||||||
// ignore_for_file: subtype_of_sealed_class
|
// ignore_for_file: subtype_of_sealed_class
|
||||||
|
|
||||||
class _FakeContact_0 extends _i1.SmartFake implements _i2.Contact {
|
class _FakeContactEntry_0 extends _i1.SmartFake implements _i2.ContactEntry {
|
||||||
_FakeContact_0(
|
_FakeContactEntry_0(
|
||||||
Object parent,
|
Object parent,
|
||||||
Invocation parentInvocation,
|
Invocation parentInvocation,
|
||||||
) : super(
|
) : super(
|
||||||
|
@ -41,46 +41,43 @@ class MockAddressBookService extends _i1.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<_i2.Contact> get contacts => (super.noSuchMethod(
|
List<_i2.ContactEntry> get contacts => (super.noSuchMethod(
|
||||||
Invocation.getter(#contacts),
|
Invocation.getter(#contacts),
|
||||||
returnValue: <_i2.Contact>[],
|
returnValue: <_i2.ContactEntry>[],
|
||||||
) as List<_i2.Contact>);
|
) as List<_i2.ContactEntry>);
|
||||||
@override
|
|
||||||
_i4.Future<List<_i2.Contact>> get addressBookEntries => (super.noSuchMethod(
|
|
||||||
Invocation.getter(#addressBookEntries),
|
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
|
||||||
@override
|
@override
|
||||||
bool get hasListeners => (super.noSuchMethod(
|
bool get hasListeners => (super.noSuchMethod(
|
||||||
Invocation.getter(#hasListeners),
|
Invocation.getter(#hasListeners),
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i2.Contact getContactById(String? id) => (super.noSuchMethod(
|
_i2.ContactEntry getContactById(String? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _FakeContact_0(
|
returnValue: _FakeContactEntry_0(
|
||||||
this,
|
this,
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getContactById,
|
#getContactById,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
) as _i2.Contact);
|
) as _i2.ContactEntry);
|
||||||
@override
|
@override
|
||||||
_i4.Future<List<_i2.Contact>> search(String? text) => (super.noSuchMethod(
|
_i4.Future<List<_i2.ContactEntry>> search(String? text) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#search,
|
#search,
|
||||||
[text],
|
[text],
|
||||||
),
|
),
|
||||||
returnValue: _i4.Future<List<_i2.Contact>>.value(<_i2.Contact>[]),
|
returnValue:
|
||||||
) as _i4.Future<List<_i2.Contact>>);
|
_i4.Future<List<_i2.ContactEntry>>.value(<_i2.ContactEntry>[]),
|
||||||
|
) as _i4.Future<List<_i2.ContactEntry>>);
|
||||||
@override
|
@override
|
||||||
bool matches(
|
bool matches(
|
||||||
String? term,
|
String? term,
|
||||||
_i2.Contact? contact,
|
_i2.ContactEntry? contact,
|
||||||
) =>
|
) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
@ -93,7 +90,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: false,
|
returnValue: false,
|
||||||
) as bool);
|
) as bool);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> addContact(_i2.Contact? contact) => (super.noSuchMethod(
|
_i4.Future<bool> addContact(_i2.ContactEntry? contact) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#addContact,
|
#addContact,
|
||||||
[contact],
|
[contact],
|
||||||
|
@ -101,7 +98,7 @@ class MockAddressBookService extends _i1.Mock
|
||||||
returnValue: _i4.Future<bool>.value(false),
|
returnValue: _i4.Future<bool>.value(false),
|
||||||
) as _i4.Future<bool>);
|
) as _i4.Future<bool>);
|
||||||
@override
|
@override
|
||||||
_i4.Future<bool> editContact(_i2.Contact? editedContact) =>
|
_i4.Future<bool> editContact(_i2.ContactEntry? editedContact) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#editContact,
|
#editContact,
|
||||||
|
|
Loading…
Reference in a new issue