parent
ec7fabdd06
commit
6fdb70cbe4
|
@ -13,7 +13,6 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:sensors_plus/sensors_plus.dart';
|
import 'package:sensors_plus/sensors_plus.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:warp/payment_uri.dart';
|
|
||||||
import 'package:warp/store.dart';
|
import 'package:warp/store.dart';
|
||||||
import 'package:warp_api/warp_api.dart';
|
import 'package:warp_api/warp_api.dart';
|
||||||
|
|
||||||
|
@ -592,36 +591,54 @@ class PnLState extends State<PnLWidget> with AutomaticKeepAliveClientMixin {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(children: [
|
return IconTheme.merge(
|
||||||
FormBuilderRadioGroup(
|
data: IconThemeData(opacity: 0.54),
|
||||||
orientation: OptionsOrientation.horizontal,
|
child:
|
||||||
name: S.of(context).pnl,
|
Column(children: [
|
||||||
initialValue: accountManager.pnlSeriesIndex,
|
Row(children: [
|
||||||
onChanged: (int? v) {
|
Expanded(child:
|
||||||
setState(() {
|
FormBuilderRadioGroup(
|
||||||
accountManager.setPnlSeriesIndex(v!);
|
orientation: OptionsOrientation.horizontal,
|
||||||
});
|
name: S.of(context).pnl,
|
||||||
},
|
initialValue: accountManager.pnlSeriesIndex,
|
||||||
options: [
|
onChanged: (int? v) {
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).price), value: 0),
|
setState(() {
|
||||||
FormBuilderFieldOption(
|
accountManager.setPnlSeriesIndex(v!);
|
||||||
child: Text(S.of(context).realized), value: 1),
|
});
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).mm), value: 2),
|
},
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).total), value: 3),
|
options: [
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).qty), value: 4),
|
FormBuilderFieldOption(child: Text(S.of(context).price), value: 0),
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).table), value: 5),
|
FormBuilderFieldOption(
|
||||||
|
child: Text(S.of(context).realized), value: 1),
|
||||||
|
FormBuilderFieldOption(child: Text(S.of(context).mm), value: 2),
|
||||||
|
FormBuilderFieldOption(child: Text(S.of(context).total), value: 3),
|
||||||
|
FormBuilderFieldOption(child: Text(S.of(context).qty), value: 4),
|
||||||
|
FormBuilderFieldOption(child: Text(S.of(context).table), value: 5),
|
||||||
|
])),
|
||||||
|
IconButton(onPressed: _onExport, icon: Icon(Icons.save)),
|
||||||
]),
|
]),
|
||||||
Observer(builder: (context) {
|
Observer(builder: (context) {
|
||||||
final _ = accountManager.pnlSorted;
|
final _ = accountManager.pnlSorted;
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(right: 20),
|
padding: EdgeInsets.only(right: 20),
|
||||||
child: accountManager.pnlSeriesIndex != 5
|
child: accountManager.pnlSeriesIndex != 5
|
||||||
? PnLChart(
|
? PnLChart(
|
||||||
accountManager.pnls, accountManager.pnlSeriesIndex)
|
accountManager.pnls, accountManager.pnlSeriesIndex)
|
||||||
: PnLTable()));
|
: PnLTable()));
|
||||||
})
|
})
|
||||||
]);
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
_onExport() async {
|
||||||
|
final csvData = accountManager.pnlSorted.map((pnl) => [
|
||||||
|
pnl.timestamp,
|
||||||
|
pnl.amount,
|
||||||
|
pnl.price,
|
||||||
|
pnl.realized,
|
||||||
|
pnl.unrealized,
|
||||||
|
pnl.realized + pnl.unrealized]).toList();
|
||||||
|
await shareCsv(csvData, 'pnl_history.csv', S.of(context).pnlHistory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
"Please authenticate to show account seed"),
|
"Please authenticate to show account seed"),
|
||||||
"pleaseConfirm": MessageLookupByLibrary.simpleMessage("Please Confirm"),
|
"pleaseConfirm": MessageLookupByLibrary.simpleMessage("Please Confirm"),
|
||||||
"pnl": MessageLookupByLibrary.simpleMessage("Pnl"),
|
"pnl": MessageLookupByLibrary.simpleMessage("Pnl"),
|
||||||
|
"pnlHistory": MessageLookupByLibrary.simpleMessage("PNL History"),
|
||||||
"preparingTransaction":
|
"preparingTransaction":
|
||||||
MessageLookupByLibrary.simpleMessage("Preparing transaction..."),
|
MessageLookupByLibrary.simpleMessage("Preparing transaction..."),
|
||||||
"price": MessageLookupByLibrary.simpleMessage("Price"),
|
"price": MessageLookupByLibrary.simpleMessage("Price"),
|
||||||
|
|
|
@ -179,6 +179,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
"pleaseConfirm":
|
"pleaseConfirm":
|
||||||
MessageLookupByLibrary.simpleMessage("Por favor, confirmar"),
|
MessageLookupByLibrary.simpleMessage("Por favor, confirmar"),
|
||||||
"pnl": MessageLookupByLibrary.simpleMessage("Pnl"),
|
"pnl": MessageLookupByLibrary.simpleMessage("Pnl"),
|
||||||
|
"pnlHistory": MessageLookupByLibrary.simpleMessage("PNL History"),
|
||||||
"preparingTransaction":
|
"preparingTransaction":
|
||||||
MessageLookupByLibrary.simpleMessage("Preparando la transacción…"),
|
MessageLookupByLibrary.simpleMessage("Preparando la transacción…"),
|
||||||
"price": MessageLookupByLibrary.simpleMessage("Precio"),
|
"price": MessageLookupByLibrary.simpleMessage("Precio"),
|
||||||
|
|
|
@ -179,6 +179,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||||
"pleaseConfirm":
|
"pleaseConfirm":
|
||||||
MessageLookupByLibrary.simpleMessage("Veuillez confirmer"),
|
MessageLookupByLibrary.simpleMessage("Veuillez confirmer"),
|
||||||
"pnl": MessageLookupByLibrary.simpleMessage("P/P"),
|
"pnl": MessageLookupByLibrary.simpleMessage("P/P"),
|
||||||
|
"pnlHistory": MessageLookupByLibrary.simpleMessage("PNL History"),
|
||||||
"preparingTransaction": MessageLookupByLibrary.simpleMessage(
|
"preparingTransaction": MessageLookupByLibrary.simpleMessage(
|
||||||
"Préparation de la transaction..."),
|
"Préparation de la transaction..."),
|
||||||
"price": MessageLookupByLibrary.simpleMessage("Prix"),
|
"price": MessageLookupByLibrary.simpleMessage("Prix"),
|
||||||
|
|
|
@ -1591,6 +1591,16 @@ class S {
|
||||||
args: [ticker],
|
args: [ticker],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `PNL History`
|
||||||
|
String get pnlHistory {
|
||||||
|
return Intl.message(
|
||||||
|
'PNL History',
|
||||||
|
name: 'pnlHistory',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:csv/csv.dart';
|
|
||||||
import 'package:path_provider/path_provider.dart';
|
|
||||||
import 'package:share_plus/share_plus.dart';
|
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
import 'generated/l10n.dart';
|
import 'generated/l10n.dart';
|
||||||
|
|
||||||
|
@ -108,13 +104,7 @@ class HistoryState extends State<HistoryWidget>
|
||||||
final csvData = accountManager.sortedTxs.map((tx) => [
|
final csvData = accountManager.sortedTxs.map((tx) => [
|
||||||
tx.fullTxId, tx.height, tx.timestamp, tx.address, tx.contact ?? '',
|
tx.fullTxId, tx.height, tx.timestamp, tx.address, tx.contact ?? '',
|
||||||
tx.value, tx.memo]).toList();
|
tx.value, tx.memo]).toList();
|
||||||
final csvConverter = ListToCsvConverter();
|
await shareCsv(csvData, 'tx_history.csv', S.of(context).transactionHistory);
|
||||||
final csv = csvConverter.convert(csvData);
|
|
||||||
Directory tempDir = await getTemporaryDirectory();
|
|
||||||
String filename = "${tempDir.path}/tx_history.csv";
|
|
||||||
final file = File(filename);
|
|
||||||
await file.writeAsString(csv);
|
|
||||||
Share.shareFiles([filename], subject: S.of(context).transactionHistory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,5 +152,6 @@
|
||||||
"tapTransactionForDetails": "Tap Transaction for Details",
|
"tapTransactionForDetails": "Tap Transaction for Details",
|
||||||
"transactionHistory": "Transaction History",
|
"transactionHistory": "Transaction History",
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
"receive": "Receive {ticker}"
|
"receive": "Receive {ticker}",
|
||||||
|
"pnlHistory": "PNL History"
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,5 +152,6 @@
|
||||||
"tapTransactionForDetails": "Tap Transaction for Details",
|
"tapTransactionForDetails": "Tap Transaction for Details",
|
||||||
"transactionHistory": "Transaction History",
|
"transactionHistory": "Transaction History",
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
"receive": "Receive {ticker}"
|
"receive": "Receive {ticker}",
|
||||||
|
"pnlHistory": "PNL History"
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,5 +152,6 @@
|
||||||
"tapTransactionForDetails": "Presser sur une Transaction pour plus de details",
|
"tapTransactionForDetails": "Presser sur une Transaction pour plus de details",
|
||||||
"transactionHistory": "Historique des Transactions",
|
"transactionHistory": "Historique des Transactions",
|
||||||
"help": "Aide",
|
"help": "Aide",
|
||||||
"receive": "Recevoir {ticker}"
|
"receive": "Recevoir {ticker}",
|
||||||
|
"pnlHistory": "PNL History"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:csv/csv.dart';
|
||||||
import 'package:currency_text_input_formatter/currency_text_input_formatter.dart';
|
import 'package:currency_text_input_formatter/currency_text_input_formatter.dart';
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -11,8 +13,10 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:local_auth/local_auth.dart';
|
import 'package:local_auth/local_auth.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:rate_my_app/rate_my_app.dart';
|
import 'package:rate_my_app/rate_my_app.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
import 'package:warp_api/warp_api.dart';
|
import 'package:warp_api/warp_api.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
@ -64,9 +68,13 @@ Future<void> initUniLinks(BuildContext context) async {
|
||||||
try {
|
try {
|
||||||
final initialLink = await getInitialLink();
|
final initialLink = await getInitialLink();
|
||||||
if (initialLink != null)
|
if (initialLink != null)
|
||||||
Navigator.of(context).pushNamed('/send', arguments: SendPageArgs(uri: initialLink));
|
Navigator.of(context).pushNamed('/send', arguments: SendPageArgs(uri: initialLink));
|
||||||
} on PlatformException {
|
} on PlatformException {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subUniLinks = linkStream.listen((String? uri) {
|
||||||
|
Navigator.of(context).pushNamed('/send', arguments: SendPageArgs(uri: uri));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleQuickAction(BuildContext context, String shortcut) {
|
void handleQuickAction(BuildContext context, String shortcut) {
|
||||||
|
@ -163,11 +171,20 @@ class ZWalletAppState extends State<ZWalletApp> {
|
||||||
await syncStatus.init();
|
await syncStatus.init();
|
||||||
await initUniLinks(context);
|
await initUniLinks(context);
|
||||||
final quickActions = QuickActions();
|
final quickActions = QuickActions();
|
||||||
quickActions.setShortcutItems(<ShortcutItem>[
|
quickActions.initialize((type) {
|
||||||
ShortcutItem(type: 'receive', localizedTitle: s.receive(coin.ticker), icon: 'receive'),
|
handleQuickAction(this.context, type);
|
||||||
ShortcutItem(type: 'send', localizedTitle: s.sendCointicker(coin.ticker), icon: 'send'),
|
});
|
||||||
]);
|
if (!settings.linkHooksInitialized) {
|
||||||
quickActions.initialize((type) { handleQuickAction(this.context, type); });
|
quickActions.setShortcutItems(<ShortcutItem>[
|
||||||
|
ShortcutItem(type: 'receive',
|
||||||
|
localizedTitle: s.receive(coin.ticker),
|
||||||
|
icon: 'receive'),
|
||||||
|
ShortcutItem(type: 'send',
|
||||||
|
localizedTitle: s.sendCointicker(coin.ticker),
|
||||||
|
icon: 'send'),
|
||||||
|
]);
|
||||||
|
await settings.setLinkHooksInitialized();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -420,3 +437,13 @@ Future<void> shieldTAddr(BuildContext context) async {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> shareCsv(List<List> data, String filename, String title) async {
|
||||||
|
final csvConverter = ListToCsvConverter();
|
||||||
|
final csv = csvConverter.convert(data);
|
||||||
|
Directory tempDir = await getTemporaryDirectory();
|
||||||
|
String fn = "${tempDir.path}/$filename";
|
||||||
|
final file = File(fn);
|
||||||
|
await file.writeAsString(csv);
|
||||||
|
await Share.shareFiles([fn], subject: title);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,11 @@ class SendState extends State<SendPage> {
|
||||||
if (widget.args?.contact != null)
|
if (widget.args?.contact != null)
|
||||||
_addressController.text = widget.args!.contact!.address;
|
_addressController.text = widget.args!.contact!.address;
|
||||||
|
|
||||||
if (widget.args?.uri != null)
|
final uri = widget.args?.uri;
|
||||||
_setPaymentURI(widget.args!.uri!);
|
if (uri != null)
|
||||||
|
Future.microtask(() {
|
||||||
|
_setPaymentURI(uri);
|
||||||
|
});
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@ part 'store.g.dart';
|
||||||
class Settings = _Settings with _$Settings;
|
class Settings = _Settings with _$Settings;
|
||||||
|
|
||||||
abstract class _Settings with Store {
|
abstract class _Settings with Store {
|
||||||
|
@observable
|
||||||
|
bool linkHooksInitialized = false;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
String ldUrl = "";
|
String ldUrl = "";
|
||||||
|
|
||||||
|
@ -78,6 +81,7 @@ abstract class _Settings with Store {
|
||||||
@action
|
@action
|
||||||
Future<bool> restore() async {
|
Future<bool> restore() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
linkHooksInitialized = prefs.getBool('link_hooks') ?? false;
|
||||||
ldUrlChoice = prefs.getString('lightwalletd_choice') ?? "Lightwalletd";
|
ldUrlChoice = prefs.getString('lightwalletd_choice') ?? "Lightwalletd";
|
||||||
ldUrl = prefs.getString('lightwalletd_custom') ?? "";
|
ldUrl = prefs.getString('lightwalletd_custom') ?? "";
|
||||||
prefs.setString('lightwalletd_choice', ldUrlChoice);
|
prefs.setString('lightwalletd_choice', ldUrlChoice);
|
||||||
|
@ -100,6 +104,13 @@ abstract class _Settings with Store {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future<void> setLinkHooksInitialized() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
linkHooksInitialized = true;
|
||||||
|
prefs.setBool('link_hooks', true);
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> setURLChoice(String choice) async {
|
Future<void> setURLChoice(String choice) async {
|
||||||
ldUrlChoice = choice;
|
ldUrlChoice = choice;
|
||||||
|
|
Loading…
Reference in New Issue