mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
feat: move address books to isar
This commit is contained in:
parent
b2c365797c
commit
524f4c5514
5 changed files with 1404 additions and 46 deletions
|
@ -3,6 +3,7 @@ import 'package:flutter_native_splash/cli_commands.dart';
|
|||
import 'package:isar/isar.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/contact_entry.dart';
|
||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||
import 'package:stackwallet/models/isar/stack_theme.dart';
|
||||
import 'package:stackwallet/utilities/amount/amount.dart';
|
||||
|
@ -37,6 +38,7 @@ class MainDB {
|
|||
EthContractSchema,
|
||||
TransactionBlockExplorerSchema,
|
||||
StackThemeSchema,
|
||||
ContactEntrySchema,
|
||||
],
|
||||
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
||||
// inspector: kDebugMode,
|
||||
|
@ -47,6 +49,45 @@ class MainDB {
|
|||
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
|
||||
TransactionBlockExplorer? getTransactionBlockExplorer({required Coin coin}) {
|
||||
return isar.transactionBlockExplorers
|
||||
|
|
24
lib/models/isar/models/contact_entry.dart
Normal file
24
lib/models/isar/models/contact_entry.dart
Normal file
|
@ -0,0 +1,24 @@
|
|||
import 'package:isar/isar.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<String> addresses;
|
||||
late final bool isFavorite;
|
||||
|
||||
@Index(unique: true, replace: true)
|
||||
late final String customId;
|
||||
}
|
1253
lib/models/isar/models/contact_entry.g.dart
Normal file
1253
lib/models/isar/models/contact_entry.g.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -102,8 +102,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
debugPrint("BUILD: $runtimeType");
|
||||
final contacts =
|
||||
ref.watch(addressBookServiceProvider.select((value) => value.contacts));
|
||||
final contacts = ref.watch(addressBookServiceProvider.select((value) => value.contacts));
|
||||
|
||||
final isDesktop = Util.isDesktop;
|
||||
return ConditionalParent(
|
||||
|
|
|
@ -1,40 +1,92 @@
|
|||
import 'package:flutter/cupertino.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/contact_address_entry.dart';
|
||||
import 'package:stackwallet/models/isar/models/contact_entry.dart';
|
||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
|
||||
class AddressBookService extends ChangeNotifier {
|
||||
Contact getContactById(String id) {
|
||||
final json = DB.instance
|
||||
.get<dynamic>(boxName: DB.boxNameAddressBook, key: id) as Map?;
|
||||
if (json == null) {
|
||||
Logging.instance
|
||||
.log("Attempted to get non existing contact", level: LogLevel.Fatal);
|
||||
throw Exception('Contact ID "$id" not found!');
|
||||
|
||||
ContactEntry turnContactToEntry({required Contact contact}) {
|
||||
String? emojiChar = contact.emojiChar;
|
||||
String name = contact.name;
|
||||
List<String> addresses = [];
|
||||
bool isFavorite = contact.isFavorite;
|
||||
String customId = contact.id;
|
||||
for (ContactAddressEntry contactAddressEntry in contact.addresses) {
|
||||
String coin = contactAddressEntry.coin.ticker;
|
||||
String address = contactAddressEntry.address;
|
||||
String label = contactAddressEntry.label;
|
||||
String? other = contactAddressEntry.other;
|
||||
addresses.add("$coin,$address,$label,$other");
|
||||
}
|
||||
return ContactEntry(
|
||||
emojiChar: emojiChar,
|
||||
name: name,
|
||||
addresses: addresses,
|
||||
isFavorite: isFavorite,
|
||||
customId: customId,
|
||||
);
|
||||
}
|
||||
|
||||
Contact turnEntryToContact({required ContactEntry contactEntry}) {
|
||||
String? emojiChar = contactEntry.emojiChar;
|
||||
String name = contactEntry.name;
|
||||
List<ContactAddressEntry> addresses = [];
|
||||
bool isFavorite = contactEntry.isFavorite;
|
||||
String id = contactEntry.customId;
|
||||
for (String addressEntry in contactEntry.addresses) {
|
||||
List<String> addressEntrySplit = addressEntry.split(",");
|
||||
Coin coin = coinFromTickerCaseInsensitive(addressEntrySplit[0]);
|
||||
String address = addressEntrySplit[1];
|
||||
String label = addressEntrySplit[2];
|
||||
String? other = addressEntrySplit[3];
|
||||
addresses.add(ContactAddressEntry(
|
||||
coin: coin,
|
||||
address: address,
|
||||
label: label,
|
||||
other: other,
|
||||
));
|
||||
}
|
||||
return Contact(
|
||||
emojiChar: emojiChar,
|
||||
name: name,
|
||||
addresses: addresses,
|
||||
isFavorite: isFavorite,
|
||||
id: id,
|
||||
);
|
||||
}
|
||||
|
||||
Contact getContactById(String id) {
|
||||
ContactEntry? contactEntry = MainDB.instance.getContactEntry(id: id);
|
||||
if (contactEntry == null) {
|
||||
return Contact(
|
||||
name: "Contact not found",
|
||||
addresses: [],
|
||||
isFavorite: false,
|
||||
);
|
||||
} else {
|
||||
return turnEntryToContact(contactEntry: contactEntry);
|
||||
}
|
||||
return Contact.fromJson(Map<String, dynamic>.from(json));
|
||||
}
|
||||
|
||||
List<Contact> get contacts {
|
||||
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;
|
||||
List<ContactEntry> contactEntries = MainDB.instance.getContactEntries();
|
||||
List<Contact> contactsList = [];
|
||||
for (ContactEntry contactEntry in contactEntries) {
|
||||
contactsList.add(turnEntryToContact(contactEntry: contactEntry));
|
||||
}
|
||||
return contactsList;
|
||||
}
|
||||
|
||||
Future<List<Contact>>? _addressBookEntries;
|
||||
Future<List<Contact>> get addressBookEntries =>
|
||||
List<Contact>? _addressBookEntries;
|
||||
List<Contact> get addressBookEntries =>
|
||||
_addressBookEntries ??= _fetchAddressBookEntries();
|
||||
|
||||
// Load address book contact entries
|
||||
Future<List<Contact>> _fetchAddressBookEntries() async {
|
||||
List<Contact> _fetchAddressBookEntries() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
|
@ -74,43 +126,32 @@ class AddressBookService extends ChangeNotifier {
|
|||
/// returns false if it provided [contact]'s id already exists in the database
|
||||
/// other true if the [contact] was saved
|
||||
Future<bool> addContact(Contact contact) async {
|
||||
if (DB.instance.containsKey<dynamic>(
|
||||
boxName: DB.boxNameAddressBook, key: contact.id)) {
|
||||
if (await MainDB.instance.isContactEntryExists(id: contact.id)) {
|
||||
return false;
|
||||
} else {
|
||||
await MainDB.instance.putContactEntry(contactEntry: turnContactToEntry(contact: contact));
|
||||
_refreshAddressBookEntries();
|
||||
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
|
||||
Future<bool> editContact(Contact editedContact) async {
|
||||
// over write the contact with edited version
|
||||
await DB.instance.put<dynamic>(
|
||||
boxName: DB.boxNameAddressBook,
|
||||
key: editedContact.id,
|
||||
value: editedContact.toMap());
|
||||
|
||||
Logging.instance.log("edit address book entry saved", level: LogLevel.Info);
|
||||
await _refreshAddressBookEntries();
|
||||
await MainDB.instance.putContactEntry(contactEntry: turnContactToEntry(contact: editedContact));
|
||||
_refreshAddressBookEntries();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Remove address book contact entry from db if it exists
|
||||
Future<void> removeContact(String id) async {
|
||||
await DB.instance.delete<dynamic>(key: id, boxName: DB.boxNameAddressBook);
|
||||
await _refreshAddressBookEntries();
|
||||
await MainDB.instance.deleteContactEntry(id: id);
|
||||
_refreshAddressBookEntries();
|
||||
}
|
||||
|
||||
Future<void> _refreshAddressBookEntries() async {
|
||||
final newAddressBookEntries = await _fetchAddressBookEntries();
|
||||
_addressBookEntries = Future(() => newAddressBookEntries);
|
||||
void _refreshAddressBookEntries() {
|
||||
final newAddressBookEntries = _fetchAddressBookEntries();
|
||||
_addressBookEntries = newAddressBookEntries;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue