diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 0000000..0010167 --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"package_info","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\package_info-0.3.2+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-0.4.1\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.4.3\\\\","dependencies":[]},{"name":"url_launcher","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher-3.0.3\\\\","dependencies":[]}],"android":[{"name":"package_info","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\package_info-0.3.2+1\\\\","dependencies":[]},{"name":"path_provider","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider-0.4.1\\\\","dependencies":[]},{"name":"shared_preferences","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences-0.4.3\\\\","dependencies":[]},{"name":"url_launcher","path":"C:\\\\Users\\\\TJ\\\\AppData\\\\Roaming\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher-3.0.3\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"package_info","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"shared_preferences","dependencies":[]},{"name":"url_launcher","dependencies":[]}],"date_created":"2020-08-09 00:30:24.358227","version":"1.21.0-8.0.pre.47"} \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 50ef5e5..4b66d7a 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -21,7 +21,7 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 28 + compileSdkVersion 29 lintOptions { disable 'InvalidPackage' @@ -30,9 +30,9 @@ android { defaultConfig { applicationId "com.trentpiercy.trace" minSdkVersion 21 - targetSdkVersion 28 - versionCode 9 - versionName "1.0.8" + targetSdkVersion 29 + versionCode 10 + versionName "1.0.9" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } diff --git a/android/gradle.properties b/android/gradle.properties index 8bd86f6..7be3d8b 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1 +1,2 @@ org.gradle.jvmargs=-Xmx1536M +android.enableR8=true diff --git a/assets/images/ampl.png b/assets/images/ampl.png new file mode 100644 index 0000000..230e186 Binary files /dev/null and b/assets/images/ampl.png differ diff --git a/assets/images/bze.png b/assets/images/bze.png new file mode 100644 index 0000000..26e1f82 Binary files /dev/null and b/assets/images/bze.png differ diff --git a/assets/images/klown.png b/assets/images/klown.png new file mode 100644 index 0000000..59ee7cc Binary files /dev/null and b/assets/images/klown.png differ diff --git a/assets/images/leo.png b/assets/images/leo.png new file mode 100644 index 0000000..4d7e608 Binary files /dev/null and b/assets/images/leo.png differ diff --git a/assets/images/matic.png b/assets/images/matic.png new file mode 100644 index 0000000..289125a Binary files /dev/null and b/assets/images/matic.png differ diff --git a/assets/images/sin.png b/assets/images/sin.png new file mode 100644 index 0000000..9614c6b Binary files /dev/null and b/assets/images/sin.png differ diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh new file mode 100644 index 0000000..66908d6 --- /dev/null +++ b/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=C:\Code\flutter" +export "FLUTTER_APPLICATION_PATH=C:\Code\trace" +export "FLUTTER_TARGET=lib\main.dart" +export "FLUTTER_BUILD_DIR=build" +export "SYMROOT=${SOURCE_ROOT}/../build\ios" +export "OTHER_LDFLAGS=$(inherited) -framework Flutter" +export "FLUTTER_FRAMEWORK_DIR=C:\Code\flutter\bin\cache\artifacts\engine\ios" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=false" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.packages" diff --git a/lib/main.dart b/lib/main.dart index df4e44d..daa1285 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -25,42 +25,47 @@ String upArrow = "⬆"; String downArrow = "⬇"; int lastUpdate; - Future getMarketData() async { - int numberOfCoins = 1500; + int pages = 5; List tempMarketListData = []; - Future _pullData(start, limit) async { + Future _pullData(page) async { var response = await http.get( - Uri.encodeFull("https://api.coinmarketcap.com/v2/ticker/" + - "?start=" + - start.toString() + - "&limit=" + - limit.toString()), + Uri.encodeFull("https://min-api.cryptocompare.com/data/top/mktcapfull?tsym=USD&limit=100" + + "&page=" + + page.toString()), headers: {"Accept": "application/json"}); - Map rawMarketListData = new JsonDecoder().convert(response.body)["data"]; - tempMarketListData.addAll(rawMarketListData.values); + List rawMarketListData = new JsonDecoder().convert(response.body)["Data"]; + tempMarketListData.addAll(rawMarketListData); } List futures = []; - for (int i = 0; i <= numberOfCoins / 100 - 1; i++) { - int start = i * 100 + 1; - int limit = i * 100 + 100; - futures.add(_pullData(start, limit)); + for (int i = 0; i < pages; i++) { + futures.add(_pullData(i)); } await Future.wait(futures); - marketListData = tempMarketListData; + marketListData = []; + // Filter out lack of financial data + for (Map coin in tempMarketListData) { + if (coin.containsKey("RAW") && coin.containsKey("CoinInfo")) { + marketListData.add(coin); + } + } + getApplicationDocumentsDirectory().then((Directory directory) async { File jsonFile = new File(directory.path + "/marketData.json"); jsonFile.writeAsStringSync(json.encode(marketListData)); }); print("Got new market data."); + lastUpdate = DateTime.now().millisecondsSinceEpoch; } void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await getApplicationDocumentsDirectory().then((Directory directory) async { File jsonFile = new File(directory.path + "/portfolio.json"); if (jsonFile.existsSync()) { @@ -80,6 +85,7 @@ void main() async { jsonFile.createSync(); jsonFile.writeAsStringSync("[]"); marketListData = []; + // getMarketData(); ?does this work? } }); diff --git a/lib/market/change_bar.dart b/lib/market/change_bar.dart index 37675f5..533d176 100644 --- a/lib/market/change_bar.dart +++ b/lib/market/change_bar.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import '../main.dart'; final Map ohlcvWidthOptions = { "1h": [ @@ -83,11 +84,11 @@ class QuickPercentChangeBar extends StatelessWidget { .apply(color: Theme.of(context).hintColor)), new Padding(padding: const EdgeInsets.only(right: 3.0)), new Text( - snapshot["percent_change_1h"] >= 0 - ? "+" + snapshot["percent_change_1h"].toString() + "%" - : snapshot["percent_change_1h"].toString() + "%", + snapshot["CHANGEPCTHOUR"] >= 0 + ? "+" + snapshot["CHANGEPCTHOUR"].toStringAsFixed(2) + "%" + : snapshot["CHANGEPCTHOUR"].toStringAsFixed(2) + "%", style: Theme.of(context).primaryTextTheme.body2.apply( - color: snapshot["percent_change_1h"] >= 0 + color: snapshot["CHANGEPCTHOUR"] >= 0 ? Colors.green : Colors.red)) ], @@ -102,34 +103,34 @@ class QuickPercentChangeBar extends StatelessWidget { .apply(color: Theme.of(context).hintColor)), new Padding(padding: const EdgeInsets.only(right: 3.0)), new Text( - snapshot["percent_change_24h"] >= 0 - ? "+" + snapshot["percent_change_24h"].toString() + "%" - : snapshot["percent_change_24h"].toString() + "%", + snapshot["CHANGEPCT24HOUR"] >= 0 + ? "+" + snapshot["CHANGEPCT24HOUR"].toStringAsFixed(2) + "%" + : snapshot["CHANGEPCT24HOUR"].toStringAsFixed(2) + "%", style: Theme.of(context).primaryTextTheme.body2.apply( - color: snapshot["percent_change_24h"] >= 0 + color: snapshot["CHANGEPCT24HOUR"] >= 0 ? Colors.green : Colors.red)) ], ), - new Row( - mainAxisSize: MainAxisSize.min, - children: [ - new Text("7D", - style: Theme.of(context) - .textTheme - .body1 - .apply(color: Theme.of(context).hintColor)), - new Padding(padding: const EdgeInsets.only(right: 3.0)), - new Text( - snapshot["percent_change_7d"] >= 0 - ? "+" + snapshot["percent_change_7d"].toString() + "%" - : snapshot["percent_change_7d"].toString() + "%", - style: Theme.of(context).primaryTextTheme.body2.apply( - color: snapshot["percent_change_7d"] >= 0 - ? Colors.green - : Colors.red)), - ], - ) + // new Row( + // mainAxisSize: MainAxisSize.min, + // children: [ + // new Text("7D", + // style: Theme.of(context) + // .textTheme + // .body1 + // .apply(color: Theme.of(context).hintColor)), + // new Padding(padding: const EdgeInsets.only(right: 3.0)), + // new Text( + // snapshot["percent_change_7d"] >= 0 + // ? "+" + snapshot["percent_change_7d"].toString() + "%" + // : snapshot["percent_change_7d"].toString() + "%", + // style: Theme.of(context).primaryTextTheme.body2.apply( + // color: snapshot["percent_change_7d"] >= 0 + // ? Colors.green + // : Colors.red)), + // ], + // ) ], ), ); diff --git a/lib/market/coin_tabs.dart b/lib/market/coin_tabs.dart index 7d78192..536befb 100644 --- a/lib/market/coin_tabs.dart +++ b/lib/market/coin_tabs.dart @@ -56,7 +56,7 @@ class CoinDetailsState extends State _makeTabs(); _tabController = new TabController(length: _tabAmt, vsync: this); - symbol = widget.snapshot["symbol"]; + symbol = widget.snapshot["CoinInfo"]["Name"]; _makeGeneralStats(); if (historyOHLCV == null) { @@ -79,7 +79,7 @@ class CoinDetailsState extends State backgroundColor: Theme.of(context).primaryColor, titleSpacing: 2.0, elevation: appBarElevation, - title: new Text(widget.snapshot["name"], + title: new Text(widget.snapshot["CoinInfo"]["FullName"], style: Theme.of(context).textTheme.title), bottom: new PreferredSize( preferredSize: const Size.fromHeight(25.0), @@ -137,7 +137,7 @@ class CoinDetailsState extends State _getGeneralStats() async { const int fifteenMin = 15*60*1000; - if (DateTime.now().millisecondsSinceEpoch - lastUpdate >= fifteenMin) { + if (lastUpdate != null && fifteenMin != null && DateTime.now().millisecondsSinceEpoch - lastUpdate >= fifteenMin) { await getMarketData(); } _makeGeneralStats(); @@ -145,8 +145,8 @@ class CoinDetailsState extends State _makeGeneralStats() { for (Map coin in marketListData) { - if (coin["symbol"] == symbol) { - generalStats = coin["quotes"]["USD"]; + if (coin["CoinInfo"]["Name"] == symbol) { + generalStats = coin["RAW"]["USD"]; break; } } @@ -237,7 +237,7 @@ class CoinDetailsState extends State "\$" + (generalStats != null ? normalizeNumNoCommas( - generalStats["price"]) + generalStats["PRICE"]) : "0"), style: Theme.of(context) .textTheme @@ -279,7 +279,7 @@ class CoinDetailsState extends State generalStats != null ? "\$" + normalizeNum( - generalStats["market_cap"]) + generalStats["MKTCAP"]) : "0", style: Theme.of(context) .textTheme @@ -291,7 +291,7 @@ class CoinDetailsState extends State generalStats != null ? "\$" + normalizeNum( - generalStats["volume_24h"]) + generalStats["TOTALVOLUME24H"]) : "0", style: Theme.of(context) .textTheme @@ -827,7 +827,7 @@ class CoinDetailsState extends State for (Map transaction in transactionList) { cost += transaction["quantity"] * transaction["price_usd"]; - value += transaction["quantity"] * generalStats["price"]; + value += transaction["quantity"] * generalStats["PRICE"]; holdings += transaction["quantity"]; } @@ -917,7 +917,7 @@ class CoinDetailsState extends State delegate: new SliverChildBuilderDelegate( (context, index) => new TransactionItem( snapshot: transactionList[index], - currentPrice: generalStats["price"], + currentPrice: generalStats["PRICE"], symbol: symbol, refreshPage: () { setState(() { diff --git a/lib/market_coin_item.dart b/lib/market_coin_item.dart index c380696..641441c 100644 --- a/lib/market_coin_item.dart +++ b/lib/market_coin_item.dart @@ -2,17 +2,17 @@ import 'package:flutter/material.dart'; import 'main.dart'; import 'market/coin_tabs.dart'; -final assetImages = ['\$pac', 'block', 'ctxc', 'ethos', 'hush', 'msr', 'pot', 'spank', 'vrc', '0xbtc', 'blz', 'cvc', 'etn', 'icn', 'mth', 'powr', 'sphtx', 'vrsc', '2give', 'bnb', 'd', 'etp', 'icx', 'mtl', 'ppc', 'srn', 'vtc', 'abt', 'bnt', 'dai', 'eur', 'ignis', 'music', 'ppp', 'stak', 'vtho', 'act', 'bnty', 'dash', 'evx', 'ilk', 'mzc', 'ppt', 'start', 'wabi', 'actn', 'booty', 'dat', 'exmo', 'ink', 'nano', 'pre', 'steem', 'wan', 'ada', 'bos', 'data', 'exp', 'ins', 'nas', 'prl', 'storj', 'waves', 'add', 'bpt', 'dbc', 'fair', 'ion', 'nav', 'pungo', 'storm', 'wax', 'adx', 'bq', 'dcn', 'fct', 'iop', 'ncash', 'pura', 'stq', 'wgr', 'ae', 'brd', 'dcr', 'fil', 'iost', 'ndz', 'qash', 'strat', 'wicc', 'aeon', 'bsd', 'deez', 'fjc', 'iotx', 'nebl', 'qiwi', 'sub', 'wings', 'aeur', 'bsv', 'dent', 'fldc', 'iq', 'neo', 'qlc', 'sumo', 'wpr', 'agi', 'btc', 'dew', 'flo', 'itc', 'neos', 'qrl', 'sys', 'wtc', 'agrs', 'btcd', 'dgb', 'fsn', 'jnt', 'neu', 'qsp', 'taas', 'x', 'aion', 'btch', 'dgd', 'ftc', 'jpy', 'nexo', 'qtum', 'tau', 'xas', 'amb', 'btcp', 'dlt', 'fuel', 'kcs', 'ngc', 'r', 'tbx', 'xbc', 'amp', 'btcz', 'dnr', 'fun', 'kin', 'nio', 'rads', 'tel', 'xbp', 'ant', 'btdx', 'dnt', 'game', 'kmd', 'nlc2', 'rap', 'ten', 'xby', 'apex', 'btg', 'dock', 'gas', 'knc', 'nlg', 'rcn', 'tern', 'xcp', 'appc', 'btm', 'doge', 'gbp', 'krb', 'nmc', 'rdd', 'tgch', 'xdn', 'ardr', 'bts', 'drgn', 'gbx', 'lbc', 'npxs', 'rdn', 'tghc', 'xem', 'arg', 'btt', 'drop', 'gbyte', 'lend', 'nuls', 'ren', 'theta', 'xin', 'ark', 'btx', 'dta', 'generic', 'link', 'nxs', 'rep', 'tix', 'xlm', 'arn', 'burst', 'dth', 'gin', 'lkk', 'nxt', 'req', 'tkn', 'xmcc', 'ary', 'call', 'dtr', 'glxt', 'loom', 'oax', 'rhoc', 'tks', 'xmg', 'ast', 'cc', 'ebst', 'gmr', 'lpt', 'ok', 'ric', 'tnb', 'xmo', 'atm', 'cdn', 'eca', 'gno', 'lrc', 'omg', 'rise', 'tnc', 'xmr', 'atom', 'cdt', 'edg', 'gnt', 'lsk', 'omni', 'rlc', 'tnt', 'xmy', 'audr', 'cenz', 'edo', 'gold', 'ltc', 'ong', 'rpx', 'tomo', 'xp', 'auto', 'chain', 'edoge', 'grc', 'lun', 'ont', 'rub', 'tpay', 'xpa', 'aywa', 'chat', 'ela', 'grin', 'maid', 'oot', 'rvn', 'trig', 'xpm', 'bab', 'chips', 'elec', 'grs', 'mana', 'ost', 'ryo', 'trtl', 'xrp', 'bat', 'cix', 'elf', 'gsc', 'mcap', 'ox', 'safe', 'trx', 'xsg', 'bay', 'clam', 'elix', 'gto', 'mco', 'part', 'salt', 'tusd', 'xtz', 'bcbc', 'cloak', 'ella', 'gup', 'mda', 'pasc', 'san', 'tzc', 'xuc', 'bcc', 'cmm', 'emc', 'gusd', 'mds', 'pasl', 'sbd', 'ubq', 'xvc', 'bcd', 'cmt', 'emc2', 'gvt', 'med', 'pax', 'sberbank', 'unity', 'xvg', 'bch', 'cnd', 'eng', 'gxlt', 'meetone', 'pay', 'sc', 'usd', 'xzc', 'bcio', 'cnx', 'enj', 'gxs', 'mft', 'payx', 'shift', 'usdc', 'yoyow', 'bcn', 'cny', 'entrp', 'gzr', 'miota', 'pgt', 'sib', 'usdt', 'zcl', 'bco', 'cob', 'eon', 'hight', 'mith', 'pink', 'sky', 'utk', 'zec', 'bcpt', 'colx', 'eop', 'hodl', 'mkr', 'pirl', 'slr', 'ven', 'zel', 'bdl', 'coqui', 'eos', 'hot', 'mln', 'pivx', 'sls', 'veri', 'zen', 'beam', 'cred', 'eql', 'hpb', 'mnx', 'plr', 'smart', 'vet', 'zest', 'bela', 'crpt', 'eqli', 'hsr', 'mnz', 'poa', 'sngls', 'via', 'zil', 'bix', 'crw', 'equa', 'ht', 'moac', 'poe', 'snm', 'vib', 'zilla', 'blcn', 'cs', 'etc', 'html', 'mod', 'polis', 'snt', 'vibe', 'zrx', 'blk', 'ctr', 'eth', 'huc', 'mona', 'poly', 'soc', 'vivo', 'cag']; +final assetImages = ['\$pac', 'block', 'ctxc', 'ethos', 'hush', 'msr', 'pot', 'spank', 'vrc', '0xbtc', 'blz', 'cvc', 'etn', 'icn', 'mth', 'powr', 'sphtx', 'vrsc', '2give', 'bnb', 'd', 'etp', 'icx', 'mtl', 'ppc', 'srn', 'vtc', 'abt', 'bnt', 'dai', 'eur', 'ignis', 'music', 'ppp', 'stak', 'vtho', 'act', 'bnty', 'dash', 'evx', 'ilk', 'mzc', 'ppt', 'start', 'wabi', 'actn', 'booty', 'dat', 'exmo', 'ink', 'nano', 'pre', 'steem', 'wan', 'ada', 'bos', 'data', 'exp', 'ins', 'nas', 'prl', 'storj', 'waves', 'add', 'bpt', 'dbc', 'fair', 'ion', 'nav', 'pungo', 'storm', 'wax', 'adx', 'bq', 'dcn', 'fct', 'iop', 'ncash', 'pura', 'stq', 'wgr', 'ae', 'brd', 'dcr', 'fil', 'iost', 'ndz', 'qash', 'strat', 'wicc', 'aeon', 'bsd', 'deez', 'fjc', 'iotx', 'nebl', 'qiwi', 'sub', 'wings', 'aeur', 'bsv', 'dent', 'fldc', 'iq', 'neo', 'qlc', 'sumo', 'wpr', 'agi', 'btc', 'dew', 'flo', 'itc', 'neos', 'qrl', 'sys', 'wtc', 'agrs', 'btcd', 'dgb', 'fsn', 'jnt', 'neu', 'qsp', 'taas', 'x', 'aion', 'btch', 'dgd', 'ftc', 'jpy', 'nexo', 'qtum', 'tau', 'xas', 'amb', 'btcp', 'dlt', 'fuel', 'kcs', 'ngc', 'r', 'tbx', 'xbc', 'amp', 'btcz', 'dnr', 'fun', 'kin', 'nio', 'rads', 'tel', 'xbp', 'ant', 'btdx', 'dnt', 'game', 'kmd', 'nlc2', 'rap', 'ten', 'xby', 'apex', 'btg', 'dock', 'gas', 'knc', 'nlg', 'rcn', 'tern', 'xcp', 'appc', 'btm', 'doge', 'gbp', 'krb', 'nmc', 'rdd', 'tgch', 'xdn', 'ardr', 'bts', 'drgn', 'gbx', 'lbc', 'npxs', 'rdn', 'tghc', 'xem', 'arg', 'btt', 'drop', 'gbyte', 'lend', 'nuls', 'ren', 'theta', 'xin', 'ark', 'btx', 'dta', 'generic', 'link', 'nxs', 'rep', 'tix', 'xlm', 'arn', 'burst', 'dth', 'gin', 'lkk', 'nxt', 'req', 'tkn', 'xmcc', 'ary', 'call', 'dtr', 'glxt', 'loom', 'oax', 'rhoc', 'tks', 'xmg', 'ast', 'cc', 'ebst', 'gmr', 'lpt', 'ok', 'ric', 'tnb', 'xmo', 'atm', 'cdn', 'eca', 'gno', 'lrc', 'omg', 'rise', 'tnc', 'xmr', 'atom', 'cdt', 'edg', 'gnt', 'lsk', 'omni', 'rlc', 'tnt', 'xmy', 'audr', 'cenz', 'edo', 'gold', 'ltc', 'ong', 'rpx', 'tomo', 'xp', 'auto', 'chain', 'edoge', 'grc', 'lun', 'ont', 'rub', 'tpay', 'xpa', 'aywa', 'chat', 'ela', 'grin', 'maid', 'oot', 'rvn', 'trig', 'xpm', 'bab', 'chips', 'elec', 'grs', 'mana', 'ost', 'ryo', 'trtl', 'xrp', 'bat', 'cix', 'elf', 'gsc', 'mcap', 'ox', 'safe', 'trx', 'xsg', 'bay', 'clam', 'elix', 'gto', 'mco', 'part', 'salt', 'tusd', 'xtz', 'bcbc', 'cloak', 'ella', 'gup', 'mda', 'pasc', 'san', 'tzc', 'xuc', 'bcc', 'cmm', 'emc', 'gusd', 'mds', 'pasl', 'sbd', 'ubq', 'xvc', 'bcd', 'cmt', 'emc2', 'gvt', 'med', 'pax', 'sberbank', 'unity', 'xvg', 'bch', 'cnd', 'eng', 'gxlt', 'meetone', 'pay', 'sc', 'usd', 'xzc', 'bcio', 'cnx', 'enj', 'gxs', 'mft', 'payx', 'shift', 'usdc', 'yoyow', 'bcn', 'cny', 'entrp', 'gzr', 'miota', 'pgt', 'sib', 'usdt', 'zcl', 'bco', 'cob', 'eon', 'hight', 'mith', 'pink', 'sky', 'utk', 'zec', 'bcpt', 'colx', 'eop', 'hodl', 'mkr', 'pirl', 'slr', 'ven', 'zel', 'bdl', 'coqui', 'eos', 'hot', 'mln', 'pivx', 'sls', 'veri', 'zen', 'beam', 'cred', 'eql', 'hpb', 'mnx', 'plr', 'smart', 'vet', 'zest', 'bela', 'crpt', 'eqli', 'hsr', 'mnz', 'poa', 'sngls', 'via', 'zil', 'bix', 'crw', 'equa', 'ht', 'moac', 'poe', 'snm', 'vib', 'zilla', 'blcn', 'cs', 'etc', 'html', 'mod', 'polis', 'snt', 'vibe', 'zrx', 'blk', 'ctr', 'eth', 'huc', 'mona', 'poly', 'soc', 'vivo', 'sin', 'leo', 'klown', 'bze', 'ampl', 'matic', 'gac']; class CoinListItem extends StatelessWidget { CoinListItem(this.snapshot, this.columnProps); final columnProps; - final snapshot; + final Map snapshot; _getImage() { - if (assetImages.contains(snapshot["symbol"].toLowerCase())) { + if (assetImages.contains(snapshot["CoinInfo"]["Name"].toLowerCase())) { return new Image.asset( - "assets/images/" + snapshot["symbol"].toLowerCase() + ".png", + "assets/images/" + snapshot["CoinInfo"]["Name"].toLowerCase() + ".png", height: 28.0); } else { return new Container(); @@ -21,16 +21,9 @@ class CoinListItem extends StatelessWidget { @override Widget build(BuildContext context) { - snapshot.forEach((k, v) { - if (v == null) { - snapshot[k] = "0"; - } - }); - snapshot["quotes"]["USD"].forEach((k, v) { - if (v == null) { - snapshot["quotes"]["USD"][k] = 0; - } - }); + if (!snapshot.containsKey("CoinInfo") || !snapshot.containsKey("RAW") || snapshot == null || snapshot.isEmpty) { + return new Container(); + } return new InkWell( onTap: () { @@ -57,7 +50,7 @@ class CoinListItem extends StatelessWidget { new Padding(padding: const EdgeInsets.only(right: 7.0)), _getImage(), new Padding(padding: const EdgeInsets.only(right: 7.0)), - new Text(snapshot["symbol"], + new Text(snapshot["CoinInfo"]["Name"], style: Theme.of(context).textTheme.body2), ], ), @@ -71,13 +64,13 @@ class CoinListItem extends StatelessWidget { new Text( "\$" + normalizeNum( - snapshot["quotes"]["USD"]["market_cap"]), + snapshot["RAW"]["USD"]["MKTCAP"]), style: Theme.of(context).textTheme.body2), new Padding(padding: const EdgeInsets.only(bottom: 4.0)), new Text( "\$" + normalizeNum( - snapshot["quotes"]["USD"]["volume_24h"]), + snapshot["RAW"]["USD"]["TOTALVOLUME24H"]), style: Theme.of(context) .textTheme .body2 @@ -92,16 +85,16 @@ class CoinListItem extends StatelessWidget { children: [ new Text("\$" + normalizeNumNoCommas( - snapshot["quotes"]["USD"]["price"])), + snapshot["RAW"]["USD"]["PRICE"])), new Padding(padding: const EdgeInsets.only(bottom: 4.0)), new Text( - (snapshot["quotes"]["USD"]["percent_change_24h"] ?? 0) >= 0 - ? "+" + (snapshot["quotes"]["USD"]["percent_change_24h"] ?? 0) + (snapshot["RAW"]["USD"]["CHANGEPCT24HOUR"] ?? 0) >= 0 + ? "+" + (snapshot["RAW"]["USD"]["CHANGEPCT24HOUR"] ?? 0) .toStringAsFixed(2) + "%" - : (snapshot["quotes"]["USD"]["percent_change_24h"] ?? 0) + : (snapshot["RAW"]["USD"]["CHANGEPCT24HOUR"] ?? 0) .toStringAsFixed(2) + "%", style: Theme.of(context).primaryTextTheme.body1.apply( - color: (snapshot["quotes"]["USD"]["percent_change_24h"] ?? 0) >= 0 + color: (snapshot["RAW"]["USD"]["CHANGEPCT24HOUR"] ?? 0) >= 0 ? Colors.green : Colors.red)), ], diff --git a/lib/portfolio/portfolio_tabs.dart b/lib/portfolio/portfolio_tabs.dart index 20c5554..552a864 100644 --- a/lib/portfolio/portfolio_tabs.dart +++ b/lib/portfolio/portfolio_tabs.dart @@ -248,8 +248,8 @@ class PortfolioTabsState extends State portfolioMap.forEach((symbol, transactions) { num currentPrice; for (Map coin in marketListData) { - if (coin["symbol"] == symbol) { - currentPrice = coin["quotes"]["USD"]["price"]; + if (coin["CoinInfo"]["Name"] == symbol) { + currentPrice = coin["RAW"]["USD"]["PRICE"]; break; } } diff --git a/lib/portfolio/transaction_sheet.dart b/lib/portfolio/transaction_sheet.dart index 4bd70e5..c7b289b 100644 --- a/lib/portfolio/transaction_sheet.dart +++ b/lib/portfolio/transaction_sheet.dart @@ -113,7 +113,7 @@ class TransactionSheetState extends State { _checkValidSymbol(String inputSymbol) async { if (symbolList == null || symbolList.isEmpty) { symbolList = []; - widget.marketListData.forEach((value) => symbolList.add(value["symbol"])); + widget.marketListData.forEach((value) => symbolList.add(value["CoinInfo"]["Name"])); } if (symbolList.contains(inputSymbol.toUpperCase())) { @@ -122,8 +122,8 @@ class TransactionSheetState extends State { _getExchangeList(); for (var value in widget.marketListData) { - if (value["symbol"] == symbol) { - price = value["quotes"]["USD"]["price"]; + if (value["CoinInfo"]["Name"] == symbol) { + price = value["RAW"]["USD"]["PRICE"]; _priceController.text = price.toString(); priceTextColor = validColor; break; diff --git a/lib/portfolio_item.dart b/lib/portfolio_item.dart index fe0f13a..67808f1 100644 --- a/lib/portfolio_item.dart +++ b/lib/portfolio_item.dart @@ -6,8 +6,8 @@ import 'market_coin_item.dart'; class PortfolioListItem extends StatelessWidget { PortfolioListItem(this.snapshot, this.columnProps); - final snapshot; final columnProps; + final Map snapshot; _getImage() { if (assetImages.contains(snapshot["symbol"].toLowerCase())) { diff --git a/lib/settings_page.dart b/lib/settings_page.dart index 99358b5..4795e4e 100644 --- a/lib/settings_page.dart +++ b/lib/settings_page.dart @@ -349,7 +349,7 @@ class ImportPageState extends State { void initState() { super.initState(); marketListData.forEach((coin) { - validSymbols.add(coin["symbol"]); + validSymbols.add(coin["CoinInfo"]["Name"]); }); } diff --git a/lib/tabs.dart b/lib/tabs.dart index 864af98..63ed9d6 100644 --- a/lib/tabs.dart +++ b/lib/tabs.dart @@ -120,35 +120,36 @@ class TabsState extends State with SingleTickerProviderStateMixin { portfolioDisplay = []; num totalPortfolioValue = 0; marketListData.forEach((coin) { - if (neededPriceSymbols.contains(coin["symbol"]) && - portfolioTotals[coin["symbol"]] != 0) { + String symbol = coin["CoinInfo"]["Name"]; + if (neededPriceSymbols.contains(symbol) && + portfolioTotals[symbol] != 0) { portfolioDisplay.add({ - "symbol": coin["symbol"], - "price_usd": coin["quotes"]["USD"]["price"], - "percent_change_24h": coin["quotes"]["USD"]["percent_change_24h"], - "percent_change_7d": coin["quotes"]["USD"]["percent_change_7d"], - "total_quantity": portfolioTotals[coin["symbol"]], - "id": coin["id"], - "name": coin["name"], + "symbol": symbol, + "price_usd": coin["RAW"]["USD"]["PRICE"], + "percent_change_24h": coin["RAW"]["USD"]["CHANGEPCT24HOUR"], + "percent_change_1h": coin["RAW"]["USD"]["CHANGEPCTHOUR"], + "total_quantity": portfolioTotals[symbol], + "id": coin["CoinInfo"]["Id"], + "name": coin["CoinInfo"]["FullName"], + "CoinInfo" : coin["CoinInfo"] }); - totalPortfolioValue += - (portfolioTotals[coin["symbol"]] * coin["quotes"]["USD"]["price"]); + totalPortfolioValue += (portfolioTotals[symbol] * coin["RAW"]["USD"]["PRICE"]); } }); num total24hChange = 0; - num total7dChange = 0; + num total1hChange = 0; portfolioDisplay.forEach((coin) { total24hChange += (coin["percent_change_24h"] * ((coin["price_usd"] * coin["total_quantity"]) / totalPortfolioValue)); - total7dChange += (coin["percent_change_7d"] * + total1hChange += (coin["percent_change_1h"] * ((coin["price_usd"] * coin["total_quantity"]) / totalPortfolioValue)); }); totalPortfolioStats = { "value_usd": totalPortfolioValue, "percent_change_24h": total24hChange, - "percent_change_7d": total7dChange + "percent_change_1h": total1hChange }; _sortPortfolioDisplay(); @@ -434,23 +435,23 @@ class TabsState extends State with SingleTickerProviderStateMixin { ), new Column( children: [ - new Text("7D Change", + new Text("1h Change", style: Theme.of(context).textTheme.caption), new Padding( padding: const EdgeInsets.symmetric(vertical: 1.0)), new Text( - totalPortfolioStats["percent_change_7d"] >= 0 + totalPortfolioStats["percent_change_1h"] >= 0 ? "+" + - totalPortfolioStats["percent_change_7d"] + totalPortfolioStats["percent_change_1h"] .toStringAsFixed(2) + "%" - : totalPortfolioStats["percent_change_7d"] + : totalPortfolioStats["percent_change_1h"] .toStringAsFixed(2) + "%", style: Theme.of(context).primaryTextTheme.body2.apply( color: totalPortfolioStats[ - "percent_change_7d"] >= + "percent_change_1h"] >= 0 ? Colors.green : Colors.red, @@ -634,11 +635,12 @@ class TabsState extends State with SingleTickerProviderStateMixin { Map globalData; Future getGlobalData() async { - var response = await http.get( - Uri.encodeFull("https://api.coinmarketcap.com/v2/global/"), - headers: {"Accept": "application/json"}); + // var response = await http.get( + // Uri.encodeFull("https://api.coinmarketcap.com/v1/global-metrics/quotes/latest"), + // headers: {"Accept": "application/json"}); - globalData = new JsonDecoder().convert(response.body)["data"]["quotes"]["USD"]; + // globalData = new JsonDecoder().convert(response.body)["data"]["quotes"]["USD"]; + globalData = null; } Future _refreshMarketPage() async { @@ -655,8 +657,8 @@ class TabsState extends State with SingleTickerProviderStateMixin { if (filter != "" && filter != null) { List tempFilteredMarketData = []; filteredMarketData.forEach((item) { - if (item["symbol"].toLowerCase().contains(filter.toLowerCase()) || - item["name"].toLowerCase().contains(filter.toLowerCase())) { + if (item["CoinInfo"]["Name"].toLowerCase().contains(filter.toLowerCase()) || + item["CoinInfo"]["FullName"].toLowerCase().contains(filter.toLowerCase())) { tempFilteredMarketData.add(item); } }); @@ -665,28 +667,42 @@ class TabsState extends State with SingleTickerProviderStateMixin { _sortMarketData(); } - List marketSortType = ["market_cap", true]; + List marketSortType = ["MKTCAP", true]; _sortMarketData() { + if (filteredMarketData == [] || filteredMarketData == null) { + return; + } + // highest to lowest if (marketSortType[1]) { - if (marketSortType[0] == "market_cap" || - marketSortType[0] == "volume_24h" || - marketSortType[0] == "percent_change_24h") { - filteredMarketData.sort((a, b) => (b["quotes"]["USD"][marketSortType[0]] ?? 0) - .compareTo(a["quotes"]["USD"][marketSortType[0]] ?? 0)); + if (marketSortType[0] == "MKTCAP" || + marketSortType[0] == "TOTALVOLUME24H" || + marketSortType[0] == "CHANGEPCT24HOUR") { + print(filteredMarketData); + filteredMarketData.sort((a, b) => (b["RAW"]["USD"][marketSortType[0]] ?? 0) + .compareTo(a["RAW"]["USD"][marketSortType[0]] ?? 0)); + if (marketSortType[0] == "MKTCAP") { + print("adding ranks to filteredMarketData"); + int i = 1; + for (Map coin in filteredMarketData) { + coin["rank"] = i; + i++; + } + } } else { + // Handle sorting by name filteredMarketData.sort( - (a, b) => (b[marketSortType[0]] ?? 0).compareTo(a[marketSortType[0]] ?? 0)); + (a, b) => (b["CoinInfo"][marketSortType[0]] ?? 0).compareTo(a["CoinInfo"][marketSortType[0]] ?? 0)); } + // lowest to highest } else { - if (marketSortType[0] == "market_cap" || - marketSortType[0] == "volume_24h" || - marketSortType[0] == "percent_change_24h") { - - filteredMarketData.sort((a, b) => (a["quotes"]["USD"][marketSortType[0]] ?? 0) - .compareTo(b["quotes"]["USD"][marketSortType[0]] ?? 0)); + if (marketSortType[0] == "MKTCAP" || + marketSortType[0] == "TOTALVOLUME24H" || + marketSortType[0] == "CHANGEPCT24HOUR") { + filteredMarketData.sort((a, b) => (a["RAW"]["USD"][marketSortType[0]] ?? 0) + .compareTo(b["RAW"]["USD"][marketSortType[0]] ?? 0)); } else { filteredMarketData.sort( - (a, b) => (a[marketSortType[0]] ?? 0).compareTo(b[marketSortType[0]] ?? 0)); + (a, b) => (a["CoinInfo"][marketSortType[0]] ?? 0).compareTo(b["CoinInfo"][marketSortType[0]] ?? 0)); } } } @@ -772,10 +788,10 @@ class TabsState extends State with SingleTickerProviderStateMixin { children: [ new InkWell( onTap: () { - if (marketSortType[0] == "symbol") { + if (marketSortType[0] == "Name") { marketSortType[1] = !marketSortType[1]; } else { - marketSortType = ["symbol", false]; + marketSortType = ["Name", false]; } setState(() { _sortMarketData(); @@ -785,7 +801,7 @@ class TabsState extends State with SingleTickerProviderStateMixin { padding: const EdgeInsets.symmetric(vertical: 8.0), width: MediaQuery.of(context).size.width * marketColumnProps[0], - child: marketSortType[0] == "symbol" + child: marketSortType[0] == "Name" ? new Text( marketSortType[1] ? "Currency " + upArrow @@ -808,10 +824,10 @@ class TabsState extends State with SingleTickerProviderStateMixin { children: [ new InkWell( onTap: () { - if (marketSortType[0] == "market_cap") { + if (marketSortType[0] == "MKTCAP") { marketSortType[1] = !marketSortType[1]; } else { - marketSortType = ["market_cap", true]; + marketSortType = ["MKTCAP", true]; } setState(() { _sortMarketData(); @@ -820,7 +836,7 @@ class TabsState extends State with SingleTickerProviderStateMixin { child: new Padding( padding: const EdgeInsets.symmetric( vertical: 8.0), - child: marketSortType[0] == "market_cap" + child: marketSortType[0] == "MKTCAP" ? new Text( marketSortType[1] ? "Market Cap " + downArrow @@ -844,10 +860,10 @@ class TabsState extends State with SingleTickerProviderStateMixin { color: Theme.of(context).hintColor)), new InkWell( onTap: () { - if (marketSortType[0] == "volume_24h") { + if (marketSortType[0] == "TOTALVOLUME24H") { marketSortType[1] = !marketSortType[1]; } else { - marketSortType = ["volume_24h", true]; + marketSortType = ["TOTALVOLUME24H", true]; } setState(() { _sortMarketData(); @@ -856,7 +872,7 @@ class TabsState extends State with SingleTickerProviderStateMixin { child: new Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), - child: marketSortType[0] == "volume_24h" + child: marketSortType[0] == "TOTALVOLUME24H" ? new Text( marketSortType[1] ? "24h " + downArrow : "24h " + upArrow, style: @@ -875,10 +891,10 @@ class TabsState extends State with SingleTickerProviderStateMixin { ), new InkWell( onTap: () { - if (marketSortType[0] == "percent_change_24h") { + if (marketSortType[0] == "CHANGEPCT24HOUR") { marketSortType[1] = !marketSortType[1]; } else { - marketSortType = ["percent_change_24h", true]; + marketSortType = ["CHANGEPCT24HOUR", true]; } setState(() { _sortMarketData(); @@ -889,7 +905,7 @@ class TabsState extends State with SingleTickerProviderStateMixin { padding: const EdgeInsets.symmetric(vertical: 8.0), width: MediaQuery.of(context).size.width * marketColumnProps[2], - child: marketSortType[0] == "percent_change_24h" + child: marketSortType[0] == "CHANGEPCT24HOUR" ? new Text( marketSortType[1] == true ? "Price/24h " + downArrow