* charts (wip)

* charts (wip)

* wip

* add asset grid

* split files

* logic wip

* proper getPrices logic

* viewmodel (wip)

* charts

* remove unused import

* remove restricted import...?

* fix background gradient when scrolling

* add safeguards for broken db

* save new pin on removal

* add safeguards for concurrency

* add haptic feedback

* fix haptic feedback

* fix fiat ticker

* reduce chart padding

* add line touch indicator

* improve touch target size on range selector

* add date/time display when viewing past amount

* merge

* remove iconSvgPath reference

* merge

* fix state for date display

* merge

* auto-reformat

* only load charts when page is opened

* merge

* reformat and apply lints

* refactor to use `Money` instead of storing amount in `String`

* add slop comment

* fix exception on division by zero

* ci

* workaround toDouble being removed

* disable strict parsing and rounding

* fix abs()

* use new currency picker sheet

* safeguard for max flutter-supported decimals

* fix amount precision

* adjust to new buy/sell

* Update lib/new-ui/pages/charts_page.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* adjust buy/sell di

* replace -> ignore

* reformat

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
malik1004x
2026-09-22 21:32:38 +03:00
committed by GitHub
co-authored by Omar Hatem
parent d38c748127
commit b88fbf32ae
94 changed files with 2544 additions and 270 deletions
+3
View File
@@ -310,4 +310,7 @@ class Money implements Comparable<Money> {
}
return currency.symbol;
}
/// new [Money] with absolute value of this instance
Money abs() => copyWith(amount: amount.abs());
}
+2
View File
@@ -44,6 +44,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
@override
String get symbol => title;
@override
String get apiString => "crypto.$title";
set enabled(bool value) => this.enabled = value;
+1
View File
@@ -20,4 +20,5 @@ abstract class Currency {
@override
int get hashCode => decimals.hashCode ^ symbol.hashCode ^ tag.hashCode;
String get apiString;
}
+77 -51
View File
@@ -1,11 +1,11 @@
import 'dart:io';
import "dart:io";
import 'package:cw_core/db/sqlite_debug.dart';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/foundation.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:path/path.dart' as p;
import "package:cw_core/db/sqlite_debug.dart";
import "package:cw_core/root_dir.dart";
import "package:cw_core/utils/print_verbose.dart";
import "package:flutter/foundation.dart";
import "package:path/path.dart" as p;
import "package:sqflite_common_ffi/sqflite_ffi.dart";
Database? db;
@@ -16,11 +16,11 @@ Future<void> _addColumnIfNotExists(
required String definition,
}) async {
final result = await db.rawQuery("PRAGMA table_info($table)");
final columnExists = result.any((row) => row['name'] == column);
final columnExists = result.any((row) => row["name"] == column);
if (!columnExists) {
await db.execute(
'ALTER TABLE $table ADD COLUMN $column $definition;',
"ALTER TABLE $table ADD COLUMN $column $definition;",
);
}
}
@@ -63,11 +63,13 @@ Future<void> _initDb({String? pathOverride}) async {
}
}
await db?.close();
db = await openDatabase(dbFile.path, version: 12,
onUpgrade: (Database db, int oldVersion, int newVersion) async {
printV("migrating: $oldVersion, $newVersion");
if (oldVersion <= 1) {
await db.execute('''
db = await openDatabase(
dbFile.path,
version: 13,
onUpgrade: (db, oldVersion, newVersion) async {
printV("migrating: $oldVersion, $newVersion");
if (oldVersion <= 1) {
await db.execute("""
DELETE FROM WalletInfo
WHERE walletInfoId NOT IN (
SELECT MIN(walletInfoId)
@@ -77,10 +79,10 @@ WHERE walletInfoId NOT IN (
CREATE UNIQUE INDEX IF NOT EXISTS idx_walletinfo_id_unique
ON WalletInfo (id);
''');
}
if (oldVersion <= 2) {
await db.execute('''
""");
}
if (oldVersion <= 2) {
await db.execute('''
CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings (
walletInfoId INTEGER,
accountIndex INTEGER DEFAULT -1,
@@ -91,12 +93,12 @@ CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings (
FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
await _addColumnIfNotExists(
db,
table: 'WalletInfo',
column: 'receiveInfoboxDismissed',
definition: 'BOOLEAN DEFAULT FALSE',
);
await _addColumnIfNotExists(
db,
table: "WalletInfo",
column: "receiveInfoboxDismissed",
definition: "BOOLEAN DEFAULT FALSE",
);
await _addColumnIfNotExists(
db,
@@ -164,6 +166,9 @@ CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings (
definition: "BOOLEAN DEFAULT FALSE",
);
}
if(oldVersion <= 12) {
await _createChartsTables(db);
}
}, onCreate: (Database db, int version) async {
await db.execute('''
CREATE TABLE WalletInfo (
@@ -195,7 +200,7 @@ CREATE TABLE WalletInfo (
);
''');
await db.execute('''
await db.execute("""
CREATE TABLE WalletInfoDerivationInfo (
walletInfoDerivationInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
address TEXT NOT NULL,
@@ -206,9 +211,9 @@ CREATE TABLE WalletInfoDerivationInfo (
scriptType TEXT,
description TEXT
);
''');
""");
await db.execute('''
await db.execute('''
CREATE TABLE WalletInfoAddress (
walletInfoAddressId INTEGER PRIMARY KEY AUTOINCREMENT,
walletInfoId INTEGER,
@@ -218,7 +223,7 @@ CREATE TABLE WalletInfoAddress (
);
''');
await db.execute('''
await db.execute("""
CREATE TABLE WalletInfoAddressInfo (
walletInfoAddressInfoId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
walletInfoId INTEGER NOT NULL,
@@ -228,9 +233,9 @@ CREATE TABLE WalletInfoAddressInfo (
mapValueLabel TEXT NOT NULL,
CONSTRAINT WalletInfoAddressInfo_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
""");
await db.execute('''
await db.execute('''
CREATE TABLE "WalletInfoAddressMap" (
walletInfoAddressMapId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
walletInfoId INTEGER NOT NULL,
@@ -239,11 +244,11 @@ CREATE TABLE "WalletInfoAddressMap" (
CONSTRAINT WalletInfoAddress_WalletInfo_FK FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
await db.execute('''
await db.execute("""
CREATE UNIQUE INDEX IF NOT EXISTS idx_walletinfo_id_unique
ON WalletInfo (id);
''');
await db.execute('''
""");
await db.execute('''
CREATE TABLE BalanceCardStyleSettings (
walletInfoId INTEGER,
accountIndex INTEGER DEFAULT -1,
@@ -257,18 +262,39 @@ CREATE TABLE BalanceCardStyleSettings (
FOREIGN KEY (walletInfoId) REFERENCES WalletInfo(walletInfoId)
);
''');
await _createBridgeTransferTable(db);
await _createNodeTable(db);
await _createTradeTable(db);
await _createErc20TokenTable(db);
await _createSplTokenTable(db);
await _createTronTokenTable(db);
await _createImportedNFTTable(db);
});
await _createBridgeTransferTable(db);
await _createNodeTable(db);
await _createTradeTable(db);
await _createChartsTables(db);
await _createErc20TokenTable(db);
await _createSplTokenTable(db);
await _createTronTokenTable(db);
await _createImportedNFTTable(db);
},
);
}
Future<void> _createChartsTables(Database db) async {
await db.execute("""
CREATE TABLE PriceData (
fromCurrency TEXT NOT NULL,
toCurrency TEXT NOT NULL,
timestamp INTEGER NOT NULL,
price TEXT NOT NULL,
PRIMARY KEY (fromCurrency, toCurrency, timestamp)
);
""");
await db.execute("""
CREATE TABLE ChartsAssets (
asset TEXT PRIMARY KEY,
isFavorite BOOLEAN DEFAULT FALSE
);
""");
}
Future<void> _createTradeTable(Database db) async {
await db.execute('''
await db.execute("""
CREATE TABLE IF NOT EXISTS Trade (
tradeId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
id TEXT NOT NULL,
@@ -323,11 +349,11 @@ CREATE TABLE IF NOT EXISTS Trade (
chainId INTEGER,
fee REAL
);
''');
await db.execute('''
""");
await db.execute("""
CREATE UNIQUE INDEX IF NOT EXISTS idx_trade_id_unique
ON Trade (id);
''');
""");
}
Future<Map<String, dynamic>> dumpDb() async {
@@ -343,7 +369,7 @@ Future<Map<String, dynamic>> dumpDb() async {
Future<List<String>> _getTableNames(Database db) async {
final tableNames = await db.rawQuery('SELECT name FROM sqlite_master WHERE type = "table"');
return tableNames.map((e) => (e["name"]).toString()).toList();
return tableNames.map((e) => e["name"].toString()).toList();
}
Future<Map<String, dynamic>> _dumpDb() async {
@@ -366,7 +392,7 @@ Future<Map<String, dynamic>> dumpCustomDb(String path) async {
}
Future<void> _createBridgeTransferTable(Database db) async {
await db.execute('''
await db.execute("""
CREATE TABLE IF NOT EXISTS BridgeTransfer (
id TEXT NOT NULL PRIMARY KEY,
wallet_id TEXT NOT NULL,
@@ -385,11 +411,11 @@ CREATE TABLE IF NOT EXISTS BridgeTransfer (
error_message TEXT,
status_message TEXT
);
''');
await db.execute('''
""");
await db.execute("""
CREATE INDEX IF NOT EXISTS idx_bridgetransfer_wallet_id
ON BridgeTransfer(wallet_id);
''');
""");
}
Future<void> _createErc20TokenTable(Database db) async {
@@ -478,7 +504,7 @@ ON TronToken (walletName, contractAddress);
}
Future<void> _createNodeTable(Database db) async {
db.execute("""
await db.execute("""
CREATE TABLE Node (
NodeId INTEGER PRIMARY KEY,
uri TEXT NOT NULL,
+3
View File
@@ -187,4 +187,7 @@ class Erc20Token extends CryptoCurrency {
@override
int get hashCode => contractAddress.hashCode;
@override
String get apiString => "evm.$contractAddress";
}
+3
View File
@@ -197,4 +197,7 @@ class SPLToken extends CryptoCurrency {
@override
int get hashCode => mintAddress.hashCode;
@override
String get apiString => "sol.$mintAddress";
}
+3
View File
@@ -175,4 +175,7 @@ class TronToken extends CryptoCurrency {
@override
int get hashCode => contractAddress.hashCode;
@override
String get apiString => "trx.$contractAddress";
}