Export P/L

Fix Payment URI scan missing amount
This commit is contained in:
Hanh 2021-10-10 10:11:40 +08:00
parent ec7fabdd06
commit 6fdb70cbe4
12 changed files with 116 additions and 52 deletions

View File

@ -13,7 +13,6 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart
import 'package:qr_flutter/qr_flutter.dart';
import 'package:sensors_plus/sensors_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:warp/payment_uri.dart';
import 'package:warp/store.dart';
import 'package:warp_api/warp_api.dart';
@ -592,36 +591,54 @@ class PnLState extends State<PnLWidget> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
return Column(children: [
FormBuilderRadioGroup(
orientation: OptionsOrientation.horizontal,
name: S.of(context).pnl,
initialValue: accountManager.pnlSeriesIndex,
onChanged: (int? v) {
setState(() {
accountManager.setPnlSeriesIndex(v!);
});
},
options: [
FormBuilderFieldOption(child: Text(S.of(context).price), value: 0),
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),
return IconTheme.merge(
data: IconThemeData(opacity: 0.54),
child:
Column(children: [
Row(children: [
Expanded(child:
FormBuilderRadioGroup(
orientation: OptionsOrientation.horizontal,
name: S.of(context).pnl,
initialValue: accountManager.pnlSeriesIndex,
onChanged: (int? v) {
setState(() {
accountManager.setPnlSeriesIndex(v!);
});
},
options: [
FormBuilderFieldOption(child: Text(S.of(context).price), value: 0),
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) {
final _ = accountManager.pnlSorted;
return Expanded(
child: Padding(
padding: EdgeInsets.only(right: 20),
child: accountManager.pnlSeriesIndex != 5
? PnLChart(
accountManager.pnls, accountManager.pnlSeriesIndex)
: PnLTable()));
})
]);
Observer(builder: (context) {
final _ = accountManager.pnlSorted;
return Expanded(
child: Padding(
padding: EdgeInsets.only(right: 20),
child: accountManager.pnlSeriesIndex != 5
? PnLChart(
accountManager.pnls, accountManager.pnlSeriesIndex)
: 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);
}
}

View File

@ -178,6 +178,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Please authenticate to show account seed"),
"pleaseConfirm": MessageLookupByLibrary.simpleMessage("Please Confirm"),
"pnl": MessageLookupByLibrary.simpleMessage("Pnl"),
"pnlHistory": MessageLookupByLibrary.simpleMessage("PNL History"),
"preparingTransaction":
MessageLookupByLibrary.simpleMessage("Preparing transaction..."),
"price": MessageLookupByLibrary.simpleMessage("Price"),

View File

@ -179,6 +179,7 @@ class MessageLookup extends MessageLookupByLibrary {
"pleaseConfirm":
MessageLookupByLibrary.simpleMessage("Por favor, confirmar"),
"pnl": MessageLookupByLibrary.simpleMessage("Pnl"),
"pnlHistory": MessageLookupByLibrary.simpleMessage("PNL History"),
"preparingTransaction":
MessageLookupByLibrary.simpleMessage("Preparando la transacción…"),
"price": MessageLookupByLibrary.simpleMessage("Precio"),

View File

@ -179,6 +179,7 @@ class MessageLookup extends MessageLookupByLibrary {
"pleaseConfirm":
MessageLookupByLibrary.simpleMessage("Veuillez confirmer"),
"pnl": MessageLookupByLibrary.simpleMessage("P/P"),
"pnlHistory": MessageLookupByLibrary.simpleMessage("PNL History"),
"preparingTransaction": MessageLookupByLibrary.simpleMessage(
"Préparation de la transaction..."),
"price": MessageLookupByLibrary.simpleMessage("Prix"),

View File

@ -1591,6 +1591,16 @@ class S {
args: [ticker],
);
}
/// `PNL History`
String get pnlHistory {
return Intl.message(
'PNL History',
name: 'pnlHistory',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@ -1,11 +1,7 @@
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.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 'generated/l10n.dart';
@ -108,13 +104,7 @@ class HistoryState extends State<HistoryWidget>
final csvData = accountManager.sortedTxs.map((tx) => [
tx.fullTxId, tx.height, tx.timestamp, tx.address, tx.contact ?? '',
tx.value, tx.memo]).toList();
final csvConverter = ListToCsvConverter();
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);
await shareCsv(csvData, 'tx_history.csv', S.of(context).transactionHistory);
}
}

View File

@ -152,5 +152,6 @@
"tapTransactionForDetails": "Tap Transaction for Details",
"transactionHistory": "Transaction History",
"help": "Help",
"receive": "Receive {ticker}"
"receive": "Receive {ticker}",
"pnlHistory": "PNL History"
}

View File

@ -152,5 +152,6 @@
"tapTransactionForDetails": "Tap Transaction for Details",
"transactionHistory": "Transaction History",
"help": "Help",
"receive": "Receive {ticker}"
"receive": "Receive {ticker}",
"pnlHistory": "PNL History"
}

View File

@ -152,5 +152,6 @@
"tapTransactionForDetails": "Presser sur une Transaction pour plus de details",
"transactionHistory": "Historique des Transactions",
"help": "Aide",
"receive": "Recevoir {ticker}"
"receive": "Recevoir {ticker}",
"pnlHistory": "PNL History"
}

View File

@ -1,7 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:ui';
import 'package:csv/csv.dart';
import 'package:currency_text_input_formatter/currency_text_input_formatter.dart';
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
@ -11,8 +13,10 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:intl/intl.dart';
import 'package:local_auth/local_auth.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:rate_my_app/rate_my_app.dart';
import 'package:share_plus/share_plus.dart';
import 'package:sqflite/sqflite.dart';
import 'package:warp_api/warp_api.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
@ -64,9 +68,13 @@ Future<void> initUniLinks(BuildContext context) async {
try {
final initialLink = await getInitialLink();
if (initialLink != null)
Navigator.of(context).pushNamed('/send', arguments: SendPageArgs(uri: initialLink));
Navigator.of(context).pushNamed('/send', arguments: SendPageArgs(uri: initialLink));
} on PlatformException {
}
subUniLinks = linkStream.listen((String? uri) {
Navigator.of(context).pushNamed('/send', arguments: SendPageArgs(uri: uri));
});
}
void handleQuickAction(BuildContext context, String shortcut) {
@ -163,11 +171,20 @@ class ZWalletAppState extends State<ZWalletApp> {
await syncStatus.init();
await initUniLinks(context);
final quickActions = QuickActions();
quickActions.setShortcutItems(<ShortcutItem>[
ShortcutItem(type: 'receive', localizedTitle: s.receive(coin.ticker), icon: 'receive'),
ShortcutItem(type: 'send', localizedTitle: s.sendCointicker(coin.ticker), icon: 'send'),
]);
quickActions.initialize((type) { handleQuickAction(this.context, type); });
quickActions.initialize((type) {
handleQuickAction(this.context, type);
});
if (!settings.linkHooksInitialized) {
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;
}
@ -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);
}

View File

@ -52,8 +52,11 @@ class SendState extends State<SendPage> {
if (widget.args?.contact != null)
_addressController.text = widget.args!.contact!.address;
if (widget.args?.uri != null)
_setPaymentURI(widget.args!.uri!);
final uri = widget.args?.uri;
if (uri != null)
Future.microtask(() {
_setPaymentURI(uri);
});
super.initState();

View File

@ -24,6 +24,9 @@ part 'store.g.dart';
class Settings = _Settings with _$Settings;
abstract class _Settings with Store {
@observable
bool linkHooksInitialized = false;
@observable
String ldUrl = "";
@ -78,6 +81,7 @@ abstract class _Settings with Store {
@action
Future<bool> restore() async {
final prefs = await SharedPreferences.getInstance();
linkHooksInitialized = prefs.getBool('link_hooks') ?? false;
ldUrlChoice = prefs.getString('lightwalletd_choice') ?? "Lightwalletd";
ldUrl = prefs.getString('lightwalletd_custom') ?? "";
prefs.setString('lightwalletd_choice', ldUrlChoice);
@ -100,6 +104,13 @@ abstract class _Settings with Store {
return true;
}
@action
Future<void> setLinkHooksInitialized() async {
final prefs = await SharedPreferences.getInstance();
linkHooksInitialized = true;
prefs.setBool('link_hooks', true);
}
@action
Future<void> setURLChoice(String choice) async {
ldUrlChoice = choice;