Localization English
This commit is contained in:
parent
15fe056456
commit
df9af5df98
|
@ -6,6 +6,7 @@ import 'package:package_info_plus/package_info_plus.dart';
|
|||
import 'package:mustache_template/mustache.dart';
|
||||
|
||||
import 'main.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
Future<void> showAbout(BuildContext context) async {
|
||||
final contentTemplate = await rootBundle.loadString('assets/about.md');
|
||||
|
@ -14,12 +15,12 @@ Future<void> showAbout(BuildContext context) async {
|
|||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
String version = packageInfo.version;
|
||||
String code = packageInfo.buildNumber;
|
||||
content += "`Version: $version+$code`";
|
||||
content += "`${S.of(context).version}: $version+$code`";
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('About ${coin.app}'),
|
||||
title: Text('${S.of(context).about} ${coin.app}'),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Container(
|
||||
width: double.maxFinite,
|
||||
|
@ -30,7 +31,7 @@ Future<void> showAbout(BuildContext context) async {
|
|||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
label: Text('OK'),
|
||||
label: Text(S.of(context).ok),
|
||||
icon: Icon(Icons.done))
|
||||
]));
|
||||
}
|
||||
|
|
146
lib/account.dart
146
lib/account.dart
|
@ -16,6 +16,7 @@ import 'package:grouped_list/grouped_list.dart';
|
|||
|
||||
import 'about.dart';
|
||||
import 'main.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
class AccountPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -94,28 +95,28 @@ class _AccountPageState extends State<AccountPage>
|
|||
builder: (context) =>
|
||||
Text("${coin.symbol} Wallet - ${accountManager.active.name}")),
|
||||
bottom: TabBar(controller: _tabController, isScrollable: true, tabs: [
|
||||
Tab(text: "Account"),
|
||||
Tab(text: "Notes"),
|
||||
Tab(text: "History"),
|
||||
Tab(text: "Budget"),
|
||||
Tab(text: "Trading P&L"),
|
||||
Tab(text: "Contacts"),
|
||||
Tab(text: S.of(context).account),
|
||||
Tab(text: S.of(context).notes),
|
||||
Tab(text: S.of(context).history),
|
||||
Tab(text: S.of(context).budget),
|
||||
Tab(text: S.of(context).tradingPl),
|
||||
Tab(text: S.of(context).contacts),
|
||||
]),
|
||||
actions: [
|
||||
Observer(builder: (context) {
|
||||
accountManager.canPay;
|
||||
return PopupMenuButton<String>(
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(child: Text("Accounts"), value: "Accounts"),
|
||||
PopupMenuItem(child: Text("Backup"), value: "Backup"),
|
||||
PopupMenuItem(child: Text("Rescan"), value: "Rescan"),
|
||||
PopupMenuItem(child: Text(S.of(context).accounts), value: "Accounts"),
|
||||
PopupMenuItem(child: Text(S.of(context).backup), value: "Backup"),
|
||||
PopupMenuItem(child: Text(S.of(context).rescan), value: "Rescan"),
|
||||
if (accountManager.canPay)
|
||||
PopupMenuItem(child: Text("Cold Storage"), value: "Cold"),
|
||||
PopupMenuItem(child: Text(S.of(context).coldStorage), value: "Cold"),
|
||||
if (accountManager.canPay)
|
||||
PopupMenuItem(child: Text('MultiPay'), value: "MultiPay"),
|
||||
PopupMenuItem(child: Text('Broadcast'), value: "Broadcast"),
|
||||
PopupMenuItem(child: Text('Settings'), value: "Settings"),
|
||||
PopupMenuItem(child: Text("About"), value: "About"),
|
||||
PopupMenuItem(child: Text(S.of(context).multipay), value: "MultiPay"),
|
||||
PopupMenuItem(child: Text(S.of(context).broadcast), value: "Broadcast"),
|
||||
PopupMenuItem(child: Text(S.of(context).settings), value: "Settings"),
|
||||
PopupMenuItem(child: Text(S.of(context).about), value: "About"),
|
||||
],
|
||||
onSelected: _onMenu,
|
||||
);
|
||||
|
@ -129,7 +130,7 @@ class _AccountPageState extends State<AccountPage>
|
|||
child: Column(children: [
|
||||
Observer(
|
||||
builder: (context) => syncStatus.syncedHeight <= 0
|
||||
? Text('Synching')
|
||||
? Text(S.of(context).synching)
|
||||
: syncStatus.isSynced()
|
||||
? Text('${syncStatus.syncedHeight}',
|
||||
style: theme.textTheme.caption)
|
||||
|
@ -145,8 +146,8 @@ class _AccountPageState extends State<AccountPage>
|
|||
return Column(children: [
|
||||
if (hasTAddr)
|
||||
Text(showTAddr
|
||||
? 'Tap QR Code for Shielded Address'
|
||||
: 'Tap QR Code for Transparent Address'),
|
||||
? S.of(context).tapQrCodeForShieldedAddress
|
||||
: S.of(context).tapQrCodeForTransparentAddress),
|
||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||
GestureDetector(
|
||||
onTap: hasTAddr ? _onQRTap : null,
|
||||
|
@ -167,14 +168,14 @@ class _AccountPageState extends State<AccountPage>
|
|||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||
if (!showTAddr)
|
||||
OutlinedButton(
|
||||
child: Text('New Snap Address'),
|
||||
child: Text(S.of(context).newSnapAddress),
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: BorderSide(
|
||||
width: 1, color: theme.primaryColor)),
|
||||
onPressed: _onSnapAddress),
|
||||
if (showTAddr)
|
||||
OutlinedButton(
|
||||
child: Text('Shield Transp. Balance'),
|
||||
child: Text(S.of(context).shieldTranspBalance),
|
||||
style: OutlinedButton.styleFrom(
|
||||
side:
|
||||
BorderSide(width: 1, color: theme.primaryColor)),
|
||||
|
@ -240,7 +241,7 @@ class _AccountPageState extends State<AccountPage>
|
|||
floatingActionButton: _accountTab
|
||||
? FloatingActionButton(
|
||||
onPressed: _onSend,
|
||||
tooltip: 'Send',
|
||||
tooltip: S.of(context).send,
|
||||
backgroundColor: Theme.of(context)
|
||||
.accentColor
|
||||
.withOpacity(accountManager.canPay ? 1.0 : 0.3),
|
||||
|
@ -268,7 +269,7 @@ class _AccountPageState extends State<AccountPage>
|
|||
|
||||
_onAddressCopy() {
|
||||
Clipboard.setData(ClipboardData(text: _address()));
|
||||
final snackBar = SnackBar(content: Text('Address copied to clipboard'));
|
||||
final snackBar = SnackBar(content: Text(S.of(context).addressCopiedToClipboard));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar);
|
||||
}
|
||||
|
||||
|
@ -277,16 +278,16 @@ class _AccountPageState extends State<AccountPage>
|
|||
context: this.context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Shield Transparent Balance'),
|
||||
title: Text(S.of(context).shieldTransparentBalance),
|
||||
content: Text(
|
||||
'Do you want to transfer your entire transparent balance to your shielded address?'),
|
||||
S.of(context).doYouWantToTransferYourEntireTransparentBalanceTo),
|
||||
actions: confirmButtons(context, () async {
|
||||
Navigator.of(this.context).pop();
|
||||
final snackBar1 =
|
||||
SnackBar(content: Text('Shielding in progress...'));
|
||||
SnackBar(content: Text(S.of(context).shieldingInProgress));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar1);
|
||||
final txid = await WarpApi.shieldTAddr(accountManager.active.id);
|
||||
final snackBar2 = SnackBar(content: Text("TX ID: $txid"));
|
||||
final snackBar2 = SnackBar(content: Text(S.of(context).txId + txid));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar2);
|
||||
})),
|
||||
);
|
||||
|
@ -406,7 +407,7 @@ class _AccountPageState extends State<AccountPage>
|
|||
final localAuth = LocalAuthentication();
|
||||
try {
|
||||
final didAuthenticate = await localAuth.authenticate(
|
||||
localizedReason: "Please authenticate to show account seed");
|
||||
localizedReason: S.of(context).pleaseAuthenticateToShowAccountSeed);
|
||||
if (didAuthenticate) {
|
||||
Navigator.of(context).pushNamed('/backup', arguments: true);
|
||||
}
|
||||
|
@ -415,7 +416,7 @@ class _AccountPageState extends State<AccountPage>
|
|||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('No Authentication Method'),
|
||||
title: Text(S.of(context).noAuthenticationMethod),
|
||||
content: Text(e.message)));
|
||||
}
|
||||
}
|
||||
|
@ -425,20 +426,20 @@ class _AccountPageState extends State<AccountPage>
|
|||
context: this.context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Rescan'),
|
||||
content: Text('Rescan wallet from the first block?'),
|
||||
title: Text(S.of(context).rescan),
|
||||
content: Text(S.of(context).rescanWalletFromTheFirstBlock),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('Cancel'),
|
||||
child: Text(S.of(context).cancel),
|
||||
onPressed: () {
|
||||
Navigator.of(this.context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text('OK'),
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(this.context).pop();
|
||||
final snackBar = SnackBar(content: Text("Rescan Requested..."));
|
||||
final snackBar = SnackBar(content: Text(S.of(context).rescanRequested));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar);
|
||||
syncStatus.setSyncHeight(0);
|
||||
WarpApi.rewindToHeight(0);
|
||||
|
@ -454,12 +455,11 @@ class _AccountPageState extends State<AccountPage>
|
|||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Cold Storage'),
|
||||
title: Text(S.of(context).coldStorage),
|
||||
content: Text(
|
||||
'Do you want to DELETE the secret key and convert this account to a watch-only account? '
|
||||
'You will not be able to spend from this device anymore. This operation is NOT reversible.'),
|
||||
S.of(context).doYouWantToDeleteTheSecretKeyAndConvert),
|
||||
actions:
|
||||
confirmButtons(context, _convertToWatchOnly, okLabel: 'DELETE')
|
||||
confirmButtons(context, _convertToWatchOnly, okLabel: S.of(context).delete)
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -524,16 +524,16 @@ class _NoteState extends State<NoteWidget> with AutomaticKeepAliveClientMixin {
|
|||
columns: [
|
||||
DataColumn(
|
||||
label: settings.showConfirmations
|
||||
? Text('Confs')
|
||||
: Text('Height'),
|
||||
? Text(S.of(context).confs)
|
||||
: Text(S.of(context).height),
|
||||
onSort: (_, __) {
|
||||
setState(() {
|
||||
settings.toggleShowConfirmations();
|
||||
});
|
||||
}),
|
||||
DataColumn(label: Text('Date/Time')),
|
||||
DataColumn(label: Text(S.of(context).datetime)),
|
||||
DataColumn(
|
||||
label: Text('Amount'),
|
||||
label: Text(S.of(context).amount),
|
||||
numeric: true,
|
||||
onSort: (_, __) {
|
||||
setState(() {
|
||||
|
@ -541,7 +541,7 @@ class _NoteState extends State<NoteWidget> with AutomaticKeepAliveClientMixin {
|
|||
});
|
||||
}),
|
||||
],
|
||||
header: Text('Select notes to EXCLUDE from payments',
|
||||
header: Text(S.of(context).selectNotesToExcludeFromPayments,
|
||||
style: Theme.of(context).textTheme.bodyText1),
|
||||
columnSpacing: 16,
|
||||
showCheckboxColumn: false,
|
||||
|
@ -652,17 +652,17 @@ class HistoryState extends State<HistoryWidget>
|
|||
columns: [
|
||||
DataColumn(
|
||||
label: settings.showConfirmations
|
||||
? Text('Confs')
|
||||
: Text('Height'),
|
||||
? Text(S.of(context).confs)
|
||||
: Text(S.of(context).height),
|
||||
onSort: (_, __) {
|
||||
setState(() {
|
||||
settings.toggleShowConfirmations();
|
||||
});
|
||||
}),
|
||||
DataColumn(label: Text('Date/Time')),
|
||||
DataColumn(label: Text('TXID')),
|
||||
DataColumn(label: Text(S.of(context).datetime)),
|
||||
DataColumn(label: Text(S.of(context).txid)),
|
||||
DataColumn(
|
||||
label: Text('Amount'),
|
||||
label: Text(S.of(context).amount),
|
||||
numeric: true,
|
||||
onSort: (_, __) {
|
||||
setState(() {
|
||||
|
@ -739,18 +739,18 @@ class BudgetState extends State<BudgetWidget>
|
|||
Expanded(
|
||||
child: Card(
|
||||
child: Column(children: [
|
||||
Text('Largest Spendings by Address',
|
||||
Text(S.of(context).largestSpendingsByAddress,
|
||||
style: Theme.of(context).textTheme.headline6),
|
||||
Expanded(
|
||||
child: SpendingChart(accountManager.spendings, _showAddress,
|
||||
_toggleAddress)),
|
||||
Text('Tap Chart to Toggle between Address and Amount',
|
||||
Text(S.of(context).tapChartToToggleBetweenAddressAndAmount,
|
||||
style: Theme.of(context).textTheme.caption)
|
||||
]))),
|
||||
Expanded(
|
||||
child: Card(
|
||||
child: Column(children: [
|
||||
Text('Account Balance History',
|
||||
Text(S.of(context).accountBalanceHistory,
|
||||
style: Theme.of(context).textTheme.headline6),
|
||||
Expanded(
|
||||
child:
|
||||
|
@ -777,7 +777,7 @@ class SpendingChart extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final seriesList = _createSeries(data, showAddress);
|
||||
final seriesList = _createSeries(data, showAddress, context);
|
||||
final color = charts.ColorUtil.fromDartColor(
|
||||
Theme.of(context).textTheme.headline5.color);
|
||||
if (seriesList[0].data.isEmpty)
|
||||
|
@ -785,7 +785,7 @@ class SpendingChart extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('No Spending in the Last 30 Days',
|
||||
Text(S.of(context).noSpendingInTheLast30Days,
|
||||
style: Theme.of(context).textTheme.headline5)
|
||||
]);
|
||||
return new charts.PieChart(seriesList,
|
||||
|
@ -805,11 +805,11 @@ class SpendingChart extends StatelessWidget {
|
|||
}
|
||||
|
||||
static List<charts.Series<Spending, String>> _createSeries(
|
||||
List<Spending> data, bool showAddress) {
|
||||
List<Spending> data, bool showAddress, BuildContext context) {
|
||||
final palette = settings.palette.makeShades(data.length + 5);
|
||||
return [
|
||||
new charts.Series<Spending, String>(
|
||||
id: 'Largest Spending Last Month',
|
||||
id: S.of(context).largestSpendingLastMonth,
|
||||
domainFn: (Spending sales, _) => sales.address,
|
||||
measureFn: (Spending sales, _) => sales.amount,
|
||||
colorFn: (_, index) => palette[index],
|
||||
|
@ -836,7 +836,7 @@ class AccountBalanceTimeChartState extends State<AccountBalanceTimeChart> {
|
|||
final axisColor = charts.ColorUtil.fromDartColor(
|
||||
Theme.of(context).textTheme.headline5.color);
|
||||
final seriesList = _createSeries(widget.data,
|
||||
charts.ColorUtil.fromDartColor(Theme.of(context).primaryColor));
|
||||
charts.ColorUtil.fromDartColor(Theme.of(context).primaryColor), context);
|
||||
return new charts.TimeSeriesChart(
|
||||
seriesList,
|
||||
animate: false,
|
||||
|
@ -860,10 +860,10 @@ class AccountBalanceTimeChartState extends State<AccountBalanceTimeChart> {
|
|||
}
|
||||
|
||||
static List<charts.Series<AccountBalance, DateTime>> _createSeries(
|
||||
List<AccountBalance> data, charts.Color lineColor) {
|
||||
List<AccountBalance> data, charts.Color lineColor, BuildContext context) {
|
||||
return [
|
||||
new charts.Series<AccountBalance, DateTime>(
|
||||
id: 'Balance',
|
||||
id: S.of(context).balance,
|
||||
colorFn: (_, __) => lineColor,
|
||||
domainFn: (AccountBalance ab, _) => ab.time,
|
||||
measureFn: (AccountBalance ab, _) => ab.balance,
|
||||
|
@ -887,7 +887,7 @@ class PnLState extends State<PnLWidget> with AutomaticKeepAliveClientMixin {
|
|||
return Column(children: [
|
||||
FormBuilderRadioGroup(
|
||||
orientation: OptionsOrientation.horizontal,
|
||||
name: 'Pnl',
|
||||
name: S.of(context).pnl,
|
||||
initialValue: accountManager.pnlSeriesIndex,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -895,12 +895,12 @@ class PnLState extends State<PnLWidget> with AutomaticKeepAliveClientMixin {
|
|||
});
|
||||
},
|
||||
options: [
|
||||
FormBuilderFieldOption(child: Text('Real'), value: 0),
|
||||
FormBuilderFieldOption(child: Text('M/M'), value: 1),
|
||||
FormBuilderFieldOption(child: Text('Total'), value: 2),
|
||||
FormBuilderFieldOption(child: Text('Price'), value: 3),
|
||||
FormBuilderFieldOption(child: Text('Qty'), value: 4),
|
||||
FormBuilderFieldOption(child: Text('Table'), value: 5),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).real), value: 0),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).mm), value: 1),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).total), value: 2),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).price), value: 3),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).qty), value: 4),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).table), value: 5),
|
||||
]),
|
||||
Observer(builder: (context) {
|
||||
final _ = accountManager.pnls;
|
||||
|
@ -924,7 +924,7 @@ class PnLChart extends StatelessWidget {
|
|||
final axisColor = charts.ColorUtil.fromDartColor(
|
||||
Theme.of(context).textTheme.headline5.color);
|
||||
final seriesList = _createSeries(data, seriesIndex,
|
||||
charts.ColorUtil.fromDartColor(Theme.of(context).primaryColor));
|
||||
charts.ColorUtil.fromDartColor(Theme.of(context).primaryColor), context);
|
||||
return new charts.TimeSeriesChart(
|
||||
seriesList,
|
||||
animate: false,
|
||||
|
@ -961,10 +961,10 @@ class PnLChart extends StatelessWidget {
|
|||
}
|
||||
|
||||
static List<charts.Series<PnL, DateTime>> _createSeries(
|
||||
List<PnL> data, int index, charts.Color lineColor) {
|
||||
List<PnL> data, int index, charts.Color lineColor, BuildContext context) {
|
||||
return [
|
||||
new charts.Series<PnL, DateTime>(
|
||||
id: 'P/L',
|
||||
id: S.of(context).pl,
|
||||
colorFn: (_, __) => lineColor,
|
||||
domainFn: (PnL pnl, _) => pnl.timestamp,
|
||||
measureFn: (PnL pnl, _) => _seriesData(pnl, index),
|
||||
|
@ -980,12 +980,12 @@ class PnLTable extends StatelessWidget {
|
|||
return SingleChildScrollView(
|
||||
child: PaginatedDataTable(
|
||||
columns: [
|
||||
DataColumn(label: Text('Date/Time')),
|
||||
DataColumn(label: Text('Qty'), numeric: true),
|
||||
DataColumn(label: Text('Price'), numeric: true),
|
||||
DataColumn(label: Text('Realized'), numeric: true),
|
||||
DataColumn(label: Text('M/M'), numeric: true),
|
||||
DataColumn(label: Text('Total'), numeric: true),
|
||||
DataColumn(label: Text(S.of(context).datetime)),
|
||||
DataColumn(label: Text(S.of(context).qty), numeric: true),
|
||||
DataColumn(label: Text(S.of(context).price), numeric: true),
|
||||
DataColumn(label: Text(S.of(context).realized), numeric: true),
|
||||
DataColumn(label: Text(S.of(context).mm), numeric: true),
|
||||
DataColumn(label: Text(S.of(context).total), numeric: true),
|
||||
],
|
||||
columnSpacing: 16,
|
||||
showCheckboxColumn: false,
|
||||
|
@ -1047,7 +1047,7 @@ class ContactsState extends State<ContactsWidget>
|
|||
return Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(children: [
|
||||
Text('To make a contact, send them a memo with "Contact: Name"',
|
||||
Text(S.of(context).toMakeAContactSendThemAMemoWithContact,
|
||||
style: Theme.of(context).textTheme.caption),
|
||||
Expanded(
|
||||
child: GroupedListView<Contact, String>(
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:warp/main.dart';
|
||||
import 'package:warp/store.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
import 'about.dart';
|
||||
|
||||
|
@ -23,11 +24,11 @@ class AccountManagerState extends State<AccountManagerPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Accounts'), actions: [
|
||||
appBar: AppBar(title: Text(S.of(context).accounts), actions: [
|
||||
PopupMenuButton<String>(
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(child: Text('Settings'), value: "Settings"),
|
||||
PopupMenuItem(child: Text("About"), value: "About"),
|
||||
PopupMenuItem(child: Text(S.of(context).settings), value: "Settings"),
|
||||
PopupMenuItem(child: Text(S.of(context).about), value: "About"),
|
||||
],
|
||||
onSelected: _onMenu)
|
||||
]),
|
||||
|
@ -35,7 +36,7 @@ class AccountManagerState extends State<AccountManagerPage> {
|
|||
builder: (context) => Stack(children: [
|
||||
accountManager.accounts.isEmpty
|
||||
? Center(
|
||||
child: Text("No account",
|
||||
child: Text(S.of(context).noAccount,
|
||||
style: Theme.of(context).textTheme.headline5))
|
||||
: ListView(
|
||||
children: accountManager.accounts
|
||||
|
@ -74,12 +75,12 @@ class AccountManagerState extends State<AccountManagerPage> {
|
|||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Seed'),
|
||||
title: Text(S.of(context).seed),
|
||||
content: Text(
|
||||
'Are you SURE you want to DELETE this account? You MUST have a BACKUP to recover it. This operation is NOT reversible.'),
|
||||
S.of(context).confirmDeleteAccount),
|
||||
actions: confirmButtons(context, () {
|
||||
Navigator.of(context).pop(true);
|
||||
}, okLabel: 'DELETE', cancelValue: false)),
|
||||
}, okLabel: S.of(context).delete, cancelValue: false)),
|
||||
);
|
||||
return confirm;
|
||||
}
|
||||
|
@ -103,7 +104,7 @@ class AccountManagerState extends State<AccountManagerPage> {
|
|||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Change Account Name'),
|
||||
title: Text(S.of(context).changeAccountName),
|
||||
content: TextField(controller: _accountNameController),
|
||||
actions: confirmButtons(context, _changeAccountName)));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:qr_flutter/qr_flutter.dart';
|
|||
|
||||
import 'main.dart';
|
||||
import 'store.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
class BackupPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -25,7 +26,7 @@ class BackupState extends State<BackupPage> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(appBar: AppBar(title: Text('Backup')), body:
|
||||
return Scaffold(appBar: AppBar(title: Text(S.of(context).backup)), body:
|
||||
FutureBuilder(
|
||||
future: _init(),
|
||||
builder: _build,
|
||||
|
@ -40,7 +41,7 @@ class BackupState extends State<BackupPage> {
|
|||
children: [
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Backup Data - Required for Restore', prefixIcon: IconButton(icon: Icon(Icons.save),
|
||||
labelText: S.of(context).backupDataRequiredForRestore, prefixIcon: IconButton(icon: Icon(Icons.save),
|
||||
onPressed: () => _showQR(backup.value()))),
|
||||
controller: _backupController,
|
||||
minLines: 3,
|
||||
|
@ -49,7 +50,7 @@ class BackupState extends State<BackupPage> {
|
|||
|
||||
),
|
||||
if (type == 0) TextField(
|
||||
decoration: InputDecoration(labelText: 'Secret Key', prefixIcon: IconButton(icon: Icon(Icons.vpn_key),
|
||||
decoration: InputDecoration(labelText: S.of(context).secretKey, prefixIcon: IconButton(icon: Icon(Icons.vpn_key),
|
||||
onPressed: () => _showQR(backup.sk))),
|
||||
controller: _skController,
|
||||
minLines: 3,
|
||||
|
@ -58,7 +59,7 @@ class BackupState extends State<BackupPage> {
|
|||
style: Theme.of(context).textTheme.caption
|
||||
),
|
||||
if (type != 2) TextField(
|
||||
decoration: InputDecoration(labelText: 'Viewing Key', prefixIcon: IconButton(icon: Icon(Icons.visibility),
|
||||
decoration: InputDecoration(labelText: S.of(context).viewingKey, prefixIcon: IconButton(icon: Icon(Icons.visibility),
|
||||
onPressed: () => _showQR(backup.ivk))),
|
||||
controller: _ivkController,
|
||||
minLines: 3,
|
||||
|
@ -67,7 +68,7 @@ class BackupState extends State<BackupPage> {
|
|||
style: Theme.of(context).textTheme.caption
|
||||
),
|
||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||
Text('Tap an icon to show the QR code'),
|
||||
Text(S.of(context).tapAnIconToShowTheQrCode),
|
||||
]
|
||||
),
|
||||
);
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||
// This is a library that looks up messages for specific locales by
|
||||
// delegating to the appropriate library.
|
||||
|
||||
// Ignore issues from commonly used lints in this file.
|
||||
// ignore_for_file:implementation_imports, file_names, unnecessary_new
|
||||
// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering
|
||||
// ignore_for_file:argument_type_not_assignable, invalid_assignment
|
||||
// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases
|
||||
// ignore_for_file:comment_references
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:intl/message_lookup_by_library.dart';
|
||||
import 'package:intl/src/intl_helpers.dart';
|
||||
|
||||
import 'messages_en.dart' as messages_en;
|
||||
import 'messages_fr.dart' as messages_fr;
|
||||
|
||||
typedef Future<dynamic> LibraryLoader();
|
||||
Map<String, LibraryLoader> _deferredLibraries = {
|
||||
'en': () => new Future.value(null),
|
||||
'fr': () => new Future.value(null),
|
||||
};
|
||||
|
||||
MessageLookupByLibrary _findExact(String localeName) {
|
||||
switch (localeName) {
|
||||
case 'en':
|
||||
return messages_en.messages;
|
||||
case 'fr':
|
||||
return messages_fr.messages;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// User programs should call this before using [localeName] for messages.
|
||||
Future<bool> initializeMessages(String localeName) async {
|
||||
var availableLocale = Intl.verifiedLocale(
|
||||
localeName,
|
||||
(locale) => _deferredLibraries[locale] != null,
|
||||
onFailure: (_) => null);
|
||||
if (availableLocale == null) {
|
||||
return new Future.value(false);
|
||||
}
|
||||
var lib = _deferredLibraries[availableLocale];
|
||||
await (lib == null ? new Future.value(false) : lib());
|
||||
initializeInternalMessageLookup(() => new CompositeMessageLookup());
|
||||
messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor);
|
||||
return new Future.value(true);
|
||||
}
|
||||
|
||||
bool _messagesExistFor(String locale) {
|
||||
try {
|
||||
return _findExact(locale) != null;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MessageLookupByLibrary _findGeneratedMessagesFor(String locale) {
|
||||
var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
|
||||
onFailure: (_) => null);
|
||||
if (actualLocale == null) return null;
|
||||
return _findExact(actualLocale);
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||
// This is a library that provides messages for a en locale. All the
|
||||
// messages from the main program should be duplicated here with the same
|
||||
// function name.
|
||||
|
||||
// Ignore issues from commonly used lints in this file.
|
||||
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||
// ignore_for_file:unused_import, file_names
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:intl/message_lookup_by_library.dart';
|
||||
|
||||
final messages = new MessageLookup();
|
||||
|
||||
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||
|
||||
class MessageLookup extends MessageLookupByLibrary {
|
||||
String get localeName => 'en';
|
||||
|
||||
static m0(currency) => "Amount in ${currency}";
|
||||
|
||||
static m1(ticker) => "Send ${ticker}";
|
||||
|
||||
static m2(ticker) => "Send ${ticker} to...";
|
||||
|
||||
static m3(amount, ticker, count) => "Sending a total of ${amount} ${ticker} to ${count} recipients";
|
||||
|
||||
static m4(aZEC, ticker, address) => "Sending ${aZEC} ${ticker} to ${address}";
|
||||
|
||||
static m5(currency) => "Use ${currency}";
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static _notInlinedMessages(_) => <String, Function> {
|
||||
"about" : MessageLookupByLibrary.simpleMessage("About"),
|
||||
"account" : MessageLookupByLibrary.simpleMessage("Account"),
|
||||
"accountBalanceHistory" : MessageLookupByLibrary.simpleMessage("Account Balance History"),
|
||||
"accountName" : MessageLookupByLibrary.simpleMessage("Account Name"),
|
||||
"accountNameIsRequired" : MessageLookupByLibrary.simpleMessage("Account name is required"),
|
||||
"accounts" : MessageLookupByLibrary.simpleMessage("Accounts"),
|
||||
"add" : MessageLookupByLibrary.simpleMessage("ADD"),
|
||||
"address" : MessageLookupByLibrary.simpleMessage("Address"),
|
||||
"addressCopiedToClipboard" : MessageLookupByLibrary.simpleMessage("Address copied to clipboard"),
|
||||
"addressIsEmpty" : MessageLookupByLibrary.simpleMessage("Address is empty"),
|
||||
"advancedOptions" : MessageLookupByLibrary.simpleMessage("Advanced Options"),
|
||||
"amount" : MessageLookupByLibrary.simpleMessage("Amount"),
|
||||
"amountInSettingscurrency" : m0,
|
||||
"amountMustBeANumber" : MessageLookupByLibrary.simpleMessage("Amount must be a number"),
|
||||
"amountMustBePositive" : MessageLookupByLibrary.simpleMessage("Amount must be positive"),
|
||||
"approve" : MessageLookupByLibrary.simpleMessage("APPROVE"),
|
||||
"backup" : MessageLookupByLibrary.simpleMessage("Backup"),
|
||||
"backupDataRequiredForRestore" : MessageLookupByLibrary.simpleMessage("Backup Data - Required for Restore"),
|
||||
"balance" : MessageLookupByLibrary.simpleMessage("Balance"),
|
||||
"blue" : MessageLookupByLibrary.simpleMessage("Blue"),
|
||||
"broadcast" : MessageLookupByLibrary.simpleMessage("Broadcast"),
|
||||
"budget" : MessageLookupByLibrary.simpleMessage("Budget"),
|
||||
"cancel" : MessageLookupByLibrary.simpleMessage("Cancel"),
|
||||
"changeAccountName" : MessageLookupByLibrary.simpleMessage("Change Account Name"),
|
||||
"coffee" : MessageLookupByLibrary.simpleMessage("Coffee"),
|
||||
"coldStorage" : MessageLookupByLibrary.simpleMessage("Cold Storage"),
|
||||
"confirmDeleteAccount" : MessageLookupByLibrary.simpleMessage("Are you SURE you want to DELETE this account? You MUST have a BACKUP to recover it. This operation is NOT reversible."),
|
||||
"confs" : MessageLookupByLibrary.simpleMessage("Confs"),
|
||||
"contacts" : MessageLookupByLibrary.simpleMessage("Contacts"),
|
||||
"currency" : MessageLookupByLibrary.simpleMessage("Currency"),
|
||||
"custom" : MessageLookupByLibrary.simpleMessage("Custom"),
|
||||
"dark" : MessageLookupByLibrary.simpleMessage("Dark"),
|
||||
"datetime" : MessageLookupByLibrary.simpleMessage("Date/Time"),
|
||||
"delete" : MessageLookupByLibrary.simpleMessage("DELETE"),
|
||||
"doYouWantToDeleteTheSecretKeyAndConvert" : MessageLookupByLibrary.simpleMessage("Do you want to DELETE the secret key and convert this account to a watch-only account? You will not be able to spend from this device anymore. This operation is NOT reversible."),
|
||||
"doYouWantToTransferYourEntireTransparentBalanceTo" : MessageLookupByLibrary.simpleMessage("Do you want to transfer your entire transparent balance to your shielded address?"),
|
||||
"enterSeed" : MessageLookupByLibrary.simpleMessage("Enter Seed, Secret Key or Viewing Key. Leave blank for a new account"),
|
||||
"height" : MessageLookupByLibrary.simpleMessage("Height"),
|
||||
"history" : MessageLookupByLibrary.simpleMessage("History"),
|
||||
"includeFeeInAmount" : MessageLookupByLibrary.simpleMessage("Include Fee in Amount"),
|
||||
"invalidAddress" : MessageLookupByLibrary.simpleMessage("Invalid Address"),
|
||||
"key" : MessageLookupByLibrary.simpleMessage("Key"),
|
||||
"largestSpendingLastMonth" : MessageLookupByLibrary.simpleMessage("Largest Spending Last Month"),
|
||||
"largestSpendingsByAddress" : MessageLookupByLibrary.simpleMessage("Largest Spendings by Address"),
|
||||
"light" : MessageLookupByLibrary.simpleMessage("Light"),
|
||||
"max" : MessageLookupByLibrary.simpleMessage("MAX"),
|
||||
"maxAmountPerNote" : MessageLookupByLibrary.simpleMessage("Max Amount per Note"),
|
||||
"memo" : MessageLookupByLibrary.simpleMessage("Memo"),
|
||||
"mm" : MessageLookupByLibrary.simpleMessage("M/M"),
|
||||
"multiPay" : MessageLookupByLibrary.simpleMessage("Multi Pay"),
|
||||
"multipay" : MessageLookupByLibrary.simpleMessage("MultiPay"),
|
||||
"na" : MessageLookupByLibrary.simpleMessage("N/A"),
|
||||
"newSnapAddress" : MessageLookupByLibrary.simpleMessage("New Snap Address"),
|
||||
"noAccount" : MessageLookupByLibrary.simpleMessage("No account"),
|
||||
"noAuthenticationMethod" : MessageLookupByLibrary.simpleMessage("No Authentication Method"),
|
||||
"noSpendingInTheLast30Days" : MessageLookupByLibrary.simpleMessage("No Spending in the Last 30 Days"),
|
||||
"notEnoughBalance" : MessageLookupByLibrary.simpleMessage("Not enough balance"),
|
||||
"notes" : MessageLookupByLibrary.simpleMessage("Notes"),
|
||||
"numberOfConfirmationsNeededBeforeSpending" : MessageLookupByLibrary.simpleMessage("Number of Confirmations Needed before Spending"),
|
||||
"ok" : MessageLookupByLibrary.simpleMessage("OK"),
|
||||
"openInExplorer" : MessageLookupByLibrary.simpleMessage("Open in Explorer"),
|
||||
"pink" : MessageLookupByLibrary.simpleMessage("Pink"),
|
||||
"pl" : MessageLookupByLibrary.simpleMessage("P/L"),
|
||||
"pleaseAuthenticateToShowAccountSeed" : MessageLookupByLibrary.simpleMessage("Please authenticate to show account seed"),
|
||||
"pleaseConfirm" : MessageLookupByLibrary.simpleMessage("Please Confirm"),
|
||||
"pnl" : MessageLookupByLibrary.simpleMessage("Pnl"),
|
||||
"preparingTransaction" : MessageLookupByLibrary.simpleMessage("Preparing transaction..."),
|
||||
"price" : MessageLookupByLibrary.simpleMessage("Price"),
|
||||
"qty" : MessageLookupByLibrary.simpleMessage("Qty"),
|
||||
"real" : MessageLookupByLibrary.simpleMessage("Real"),
|
||||
"realized" : MessageLookupByLibrary.simpleMessage("Realized"),
|
||||
"rescan" : MessageLookupByLibrary.simpleMessage("Rescan"),
|
||||
"rescanRequested" : MessageLookupByLibrary.simpleMessage("Rescan Requested..."),
|
||||
"rescanWalletFromTheFirstBlock" : MessageLookupByLibrary.simpleMessage("Rescan wallet from the first block?"),
|
||||
"retrieveTransactionDetails" : MessageLookupByLibrary.simpleMessage("Retrieve Transaction Details"),
|
||||
"roundToMillis" : MessageLookupByLibrary.simpleMessage("Round to millis"),
|
||||
"scanStartingMomentarily" : MessageLookupByLibrary.simpleMessage("Scan starting momentarily"),
|
||||
"secretKey" : MessageLookupByLibrary.simpleMessage("Secret Key"),
|
||||
"seed" : MessageLookupByLibrary.simpleMessage("Seed"),
|
||||
"selectNotesToExcludeFromPayments" : MessageLookupByLibrary.simpleMessage("Select notes to EXCLUDE from payments"),
|
||||
"send" : MessageLookupByLibrary.simpleMessage("Send"),
|
||||
"sendCointicker" : m1,
|
||||
"sendCointickerTo" : m2,
|
||||
"sendingATotalOfAmountCointickerToCountRecipients" : m3,
|
||||
"sendingAzecCointickerToAddress" : m4,
|
||||
"server" : MessageLookupByLibrary.simpleMessage("Server"),
|
||||
"settings" : MessageLookupByLibrary.simpleMessage("Settings"),
|
||||
"shieldTranspBalance" : MessageLookupByLibrary.simpleMessage("Shield Transp. Balance"),
|
||||
"shieldTransparentBalance" : MessageLookupByLibrary.simpleMessage("Shield Transparent Balance"),
|
||||
"shieldingInProgress" : MessageLookupByLibrary.simpleMessage("Shielding in progress..."),
|
||||
"spendable" : MessageLookupByLibrary.simpleMessage("Spendable:"),
|
||||
"synching" : MessageLookupByLibrary.simpleMessage("Synching"),
|
||||
"table" : MessageLookupByLibrary.simpleMessage("Table"),
|
||||
"tapAnIconToShowTheQrCode" : MessageLookupByLibrary.simpleMessage("Tap an icon to show the QR code"),
|
||||
"tapChartToToggleBetweenAddressAndAmount" : MessageLookupByLibrary.simpleMessage("Tap Chart to Toggle between Address and Amount"),
|
||||
"tapQrCodeForShieldedAddress" : MessageLookupByLibrary.simpleMessage("Tap QR Code for Shielded Address"),
|
||||
"tapQrCodeForTransparentAddress" : MessageLookupByLibrary.simpleMessage("Tap QR Code for Transparent Address"),
|
||||
"theme" : MessageLookupByLibrary.simpleMessage("Theme"),
|
||||
"timestamp" : MessageLookupByLibrary.simpleMessage("Timestamp"),
|
||||
"toMakeAContactSendThemAMemoWithContact" : MessageLookupByLibrary.simpleMessage("To make a contact, send them a memo with Contact:"),
|
||||
"total" : MessageLookupByLibrary.simpleMessage("Total"),
|
||||
"tradingPl" : MessageLookupByLibrary.simpleMessage("Trading P&L"),
|
||||
"transactionDetails" : MessageLookupByLibrary.simpleMessage("Transaction Details"),
|
||||
"txId" : MessageLookupByLibrary.simpleMessage("TX ID:"),
|
||||
"txid" : MessageLookupByLibrary.simpleMessage("TXID"),
|
||||
"unsignedTransactionFile" : MessageLookupByLibrary.simpleMessage("Unsigned Transaction File"),
|
||||
"useSettingscurrency" : m5,
|
||||
"version" : MessageLookupByLibrary.simpleMessage("Version"),
|
||||
"viewingKey" : MessageLookupByLibrary.simpleMessage("Viewing Key")
|
||||
};
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||
// This is a library that provides messages for a fr locale. All the
|
||||
// messages from the main program should be duplicated here with the same
|
||||
// function name.
|
||||
|
||||
// Ignore issues from commonly used lints in this file.
|
||||
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||
// ignore_for_file:unused_import, file_names
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:intl/message_lookup_by_library.dart';
|
||||
|
||||
final messages = new MessageLookup();
|
||||
|
||||
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||
|
||||
class MessageLookup extends MessageLookupByLibrary {
|
||||
String get localeName => 'fr';
|
||||
|
||||
static m0(currency) => "********";
|
||||
|
||||
static m1(ticker) => "********";
|
||||
|
||||
static m2(ticker) => "********";
|
||||
|
||||
static m3(amount, ticker, count) => "********";
|
||||
|
||||
static m4(aZEC, ticker, address) => "********";
|
||||
|
||||
static m5(currency) => "********";
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static _notInlinedMessages(_) => <String, Function> {
|
||||
"about" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"account" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"accountBalanceHistory" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"accountName" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"accountNameIsRequired" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"accounts" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"add" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"address" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"addressCopiedToClipboard" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"addressIsEmpty" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"advancedOptions" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"amount" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"amountInSettingscurrency" : m0,
|
||||
"amountMustBeANumber" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"amountMustBePositive" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"approve" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"backup" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"backupDataRequiredForRestore" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"balance" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"blue" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"broadcast" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"budget" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"cancel" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"changeAccountName" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"coffee" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"coldStorage" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"confirmDeleteAccount" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"confs" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"contacts" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"currency" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"custom" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"dark" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"datetime" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"delete" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"doYouWantToDeleteTheSecretKeyAndConvert" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"doYouWantToTransferYourEntireTransparentBalanceTo" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"enterSeed" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"height" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"history" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"includeFeeInAmount" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"invalidAddress" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"key" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"largestSpendingLastMonth" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"largestSpendingsByAddress" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"light" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"max" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"maxAmountPerNote" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"memo" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"mm" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"multiPay" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"multipay" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"na" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"newSnapAddress" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"noAccount" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"noAuthenticationMethod" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"noSpendingInTheLast30Days" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"notEnoughBalance" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"notes" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"numberOfConfirmationsNeededBeforeSpending" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"ok" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"openInExplorer" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"pink" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"pl" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"pleaseAuthenticateToShowAccountSeed" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"pleaseConfirm" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"pnl" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"preparingTransaction" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"price" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"qty" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"real" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"realized" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"rescan" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"rescanRequested" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"rescanWalletFromTheFirstBlock" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"retrieveTransactionDetails" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"roundToMillis" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"scanStartingMomentarily" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"secretKey" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"seed" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"selectNotesToExcludeFromPayments" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"send" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"sendCointicker" : m1,
|
||||
"sendCointickerTo" : m2,
|
||||
"sendingATotalOfAmountCointickerToCountRecipients" : m3,
|
||||
"sendingAzecCointickerToAddress" : m4,
|
||||
"server" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"settings" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"shieldTranspBalance" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"shieldTransparentBalance" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"shieldingInProgress" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"spendable" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"synching" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"table" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"tapAnIconToShowTheQrCode" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"tapChartToToggleBetweenAddressAndAmount" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"tapQrCodeForShieldedAddress" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"tapQrCodeForTransparentAddress" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"theme" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"timestamp" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"toMakeAContactSendThemAMemoWithContact" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"total" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"tradingPl" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"transactionDetails" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"txId" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"txid" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"unsignedTransactionFile" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"useSettingscurrency" : m5,
|
||||
"version" : MessageLookupByLibrary.simpleMessage("********"),
|
||||
"viewingKey" : MessageLookupByLibrary.simpleMessage("********")
|
||||
};
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
node_modules/
|
|
@ -0,0 +1,8 @@
|
|||
const _ = require('lodash')
|
||||
const fs = require('fs')
|
||||
|
||||
const t = fs.readFileSync('./intl_en.arb')
|
||||
const tr = JSON.parse(t)
|
||||
|
||||
const tr2 = _.mapValues(tr, v => '********')
|
||||
console.log(JSON.stringify(tr2))
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"version": "Version",
|
||||
"about": "About",
|
||||
"ok": "OK",
|
||||
"account": "Account",
|
||||
"notes": "Notes",
|
||||
"history": "History",
|
||||
"budget": "Budget",
|
||||
"tradingPl": "Trading P&L",
|
||||
"contacts": "Contacts",
|
||||
"accounts": "Accounts",
|
||||
"backup": "Backup",
|
||||
"rescan": "Rescan",
|
||||
"coldStorage": "Cold Storage",
|
||||
"multipay": "MultiPay",
|
||||
"broadcast": "Broadcast",
|
||||
"settings": "Settings",
|
||||
"synching": "Synching",
|
||||
"tapQrCodeForShieldedAddress": "Tap QR Code for Shielded Address",
|
||||
"tapQrCodeForTransparentAddress": "Tap QR Code for Transparent Address",
|
||||
"addressCopiedToClipboard": "Address copied to clipboard",
|
||||
"shieldTransparentBalance": "Shield Transparent Balance",
|
||||
"doYouWantToTransferYourEntireTransparentBalanceTo": "Do you want to transfer your entire transparent balance to your shielded address?",
|
||||
"shieldingInProgress": "Shielding in progress...",
|
||||
"txId": "TX ID:",
|
||||
"pleaseAuthenticateToShowAccountSeed": "Please authenticate to show account seed",
|
||||
"noAuthenticationMethod": "No Authentication Method",
|
||||
"rescanWalletFromTheFirstBlock": "Rescan wallet from the first block?",
|
||||
"cancel": "Cancel",
|
||||
"rescanRequested": "Rescan Requested...",
|
||||
"doYouWantToDeleteTheSecretKeyAndConvert": "Do you want to DELETE the secret key and convert this account to a watch-only account? You will not be able to spend from this device anymore. This operation is NOT reversible.",
|
||||
"delete": "DELETE",
|
||||
"confs": "Confs",
|
||||
"height": "Height",
|
||||
"datetime": "Date/Time",
|
||||
"amount": "Amount",
|
||||
"selectNotesToExcludeFromPayments": "Select notes to EXCLUDE from payments",
|
||||
"txid": "TXID",
|
||||
"largestSpendingsByAddress": "Largest Spendings by Address",
|
||||
"tapChartToToggleBetweenAddressAndAmount": "Tap Chart to Toggle between Address and Amount",
|
||||
"accountBalanceHistory": "Account Balance History",
|
||||
"noSpendingInTheLast30Days": "No Spending in the Last 30 Days",
|
||||
"largestSpendingLastMonth": "Largest Spending Last Month",
|
||||
"balance": "Balance",
|
||||
"pnl": "Pnl",
|
||||
"real": "Real",
|
||||
"mm": "M/M",
|
||||
"total": "Total",
|
||||
"price": "Price",
|
||||
"qty": "Qty",
|
||||
"table": "Table",
|
||||
"pl": "P/L",
|
||||
"realized": "Realized",
|
||||
"toMakeAContactSendThemAMemoWithContact": "To make a contact, send them a memo with Contact:",
|
||||
"newSnapAddress": "New Snap Address",
|
||||
"shieldTranspBalance": "Shield Transp. Balance",
|
||||
"send": "Send",
|
||||
"noAccount": "No account",
|
||||
"seed": "Seed",
|
||||
"confirmDeleteAccount": "Are you SURE you want to DELETE this account? You MUST have a BACKUP to recover it. This operation is NOT reversible.",
|
||||
"changeAccountName": "Change Account Name",
|
||||
"backupDataRequiredForRestore": "Backup Data - Required for Restore",
|
||||
"secretKey": "Secret Key",
|
||||
"viewingKey": "Viewing Key",
|
||||
"tapAnIconToShowTheQrCode": "Tap an icon to show the QR code",
|
||||
"multiPay": "Multi Pay",
|
||||
"pleaseConfirm": "Please Confirm",
|
||||
"sendingATotalOfAmountCointickerToCountRecipients": "Sending a total of {amount} {ticker} to {count} recipients",
|
||||
"preparingTransaction": "Preparing transaction...",
|
||||
"sendCointickerTo": "Send {ticker} to...",
|
||||
"addressIsEmpty": "Address is empty",
|
||||
"invalidAddress": "Invalid Address",
|
||||
"amountMustBeANumber": "Amount must be a number",
|
||||
"amountMustBePositive": "Amount must be positive",
|
||||
"accountName": "Account Name",
|
||||
"accountNameIsRequired": "Account name is required",
|
||||
"enterSeed": "Enter Seed, Secret Key or Viewing Key. Leave blank for a new account",
|
||||
"scanStartingMomentarily": "Scan starting momentarily",
|
||||
"key": "Key",
|
||||
"sendCointicker": "Send {ticker}",
|
||||
"max": "MAX",
|
||||
"advancedOptions": "Advanced Options",
|
||||
"memo": "Memo",
|
||||
"roundToMillis": "Round to millis",
|
||||
"useSettingscurrency": "Use {currency}",
|
||||
"includeFeeInAmount": "Include Fee in Amount",
|
||||
"maxAmountPerNote": "Max Amount per Note",
|
||||
"spendable": "Spendable:",
|
||||
"notEnoughBalance": "Not enough balance",
|
||||
"approve": "APPROVE",
|
||||
"sendingAzecCointickerToAddress": "Sending {aZEC} {ticker} to {address}",
|
||||
"unsignedTransactionFile": "Unsigned Transaction File",
|
||||
"amountInSettingscurrency": "Amount in {currency}",
|
||||
"custom": "Custom",
|
||||
"server": "Server",
|
||||
"blue": "Blue",
|
||||
"pink": "Pink",
|
||||
"coffee": "Coffee",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"currency": "Currency",
|
||||
"numberOfConfirmationsNeededBeforeSpending": "Number of Confirmations Needed before Spending",
|
||||
"retrieveTransactionDetails": "Retrieve Transaction Details",
|
||||
"theme": "Theme",
|
||||
"transactionDetails": "Transaction Details",
|
||||
"timestamp": "Timestamp",
|
||||
"address": "Address",
|
||||
"openInExplorer": "Open in Explorer",
|
||||
"na": "N/A",
|
||||
"add": "ADD"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"version":"********","about":"********","ok":"********","account":"********","notes":"********","history":"********","budget":"********","tradingPl":"********","contacts":"********","accounts":"********","backup":"********","rescan":"********","coldStorage":"********","multipay":"********","broadcast":"********","settings":"********","synching":"********","tapQrCodeForShieldedAddress":"********","tapQrCodeForTransparentAddress":"********","addressCopiedToClipboard":"********","shieldTransparentBalance":"********","doYouWantToTransferYourEntireTransparentBalanceTo":"********","shieldingInProgress":"********","txId":"********","pleaseAuthenticateToShowAccountSeed":"********","noAuthenticationMethod":"********","rescanWalletFromTheFirstBlock":"********","cancel":"********","rescanRequested":"********","doYouWantToDeleteTheSecretKeyAndConvert":"********","delete":"********","confs":"********","height":"********","datetime":"********","amount":"********","selectNotesToExcludeFromPayments":"********","txid":"********","largestSpendingsByAddress":"********","tapChartToToggleBetweenAddressAndAmount":"********","accountBalanceHistory":"********","noSpendingInTheLast30Days":"********","largestSpendingLastMonth":"********","balance":"********","pnl":"********","real":"********","mm":"********","total":"********","price":"********","qty":"********","table":"********","pl":"********","realized":"********","toMakeAContactSendThemAMemoWithContact":"********","newSnapAddress":"********","shieldTranspBalance":"********","send":"********","noAccount":"********","seed":"********","confirmDeleteAccount":"********","changeAccountName":"********","backupDataRequiredForRestore":"********","secretKey":"********","viewingKey":"********","tapAnIconToShowTheQrCode":"********","multiPay":"********","pleaseConfirm":"********","sendingATotalOfAmountCointickerToCountRecipients":"********","preparingTransaction":"********","sendCointickerTo":"********","addressIsEmpty":"********","invalidAddress":"********","amountMustBeANumber":"********","amountMustBePositive":"********","accountName":"********","accountNameIsRequired":"********","enterSeed":"********","scanStartingMomentarily":"********","key":"********","sendCointicker":"********","max":"********","advancedOptions":"********","memo":"********","roundToMillis":"********","useSettingscurrency":"********","includeFeeInAmount":"********","maxAmountPerNote":"********","spendable":"********","notEnoughBalance":"********","approve":"********","sendingAzecCointickerToAddress":"********","unsignedTransactionFile":"********","amountInSettingscurrency":"********","custom":"********","server":"********","blue":"********","pink":"********","coffee":"********","light":"********","dark":"********","currency":"********","numberOfConfirmationsNeededBeforeSpending":"********","retrieveTransactionDetails":"********","theme":"********","transactionDetails":"********","timestamp":"********","address":"********","openInExplorer":"********","na":"********","add": "********"}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "l10n",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"version":"********","about":"********","ok":"********","account":"********","notes":"********","history":"********","budget":"********","tradingPl":"********","contacts":"********","accounts":"********","backup":"********","rescan":"********","coldStorage":"********","multipay":"********","broadcast":"********","settings":"********","synching":"********","tapQrCodeForShieldedAddress":"********","tapQrCodeForTransparentAddress":"********","addressCopiedToClipboard":"********","shieldTransparentBalance":"********","doYouWantToTransferYourEntireTransparentBalanceTo":"********","shieldingInProgress":"********","txId":"********","pleaseAuthenticateToShowAccountSeed":"********","noAuthenticationMethod":"********","rescanWalletFromTheFirstBlock":"********","cancel":"********","rescanRequested":"********","doYouWantToDeleteTheSecretKeyAndConvert":"********","delete":"********","confs":"********","height":"********","datetime":"********","amount":"********","selectNotesToExcludeFromPayments":"********","txid":"********","largestSpendingsByAddress":"********","tapChartToToggleBetweenAddressAndAmount":"********","accountBalanceHistory":"********","noSpendingInTheLast30Days":"********","largestSpendingLastMonth":"********","balance":"********","pnl":"********","real":"********","mm":"********","total":"********","price":"********","qty":"********","table":"********","pl":"********","realized":"********","toMakeAContactSendThemAMemoWithContact":"********","newSnapAddress":"********","shieldTranspBalance":"********","send":"********","noAccount":"********","seed":"********","confirmDeleteAccount":"********","changeAccountName":"********","backupDataRequiredForRestore":"********","secretKey":"********","viewingKey":"********","tapAnIconToShowTheQrCode":"********","multiPay":"********","pleaseConfirm":"********","sendingATotalOfAmountCointickerToCountRecipients":"********","preparingTransaction":"********","sendCointickerTo":"********","addressIsEmpty":"********","invalidAddress":"********","amountMustBeANumber":"********","amountMustBePositive":"********","accountName":"********","accountNameIsRequired":"********","enterSeed":"********","scanStartingMomentarily":"********","key":"********","sendCointicker":"********","max":"********","advancedOptions":"********","memo":"********","roundToMillis":"********","useSettingscurrency":"********","includeFeeInAmount":"********","maxAmountPerNote":"********","spendable":"********","notEnoughBalance":"********","approve":"********","sendingAzecCointickerToAddress":"********","unsignedTransactionFile":"********","amountInSettingscurrency":"********","custom":"********","server":"********","blue":"********","pink":"********","coffee":"********","light":"********","dark":"********","currency":"********","numberOfConfirmationsNeededBeforeSpending":"********","retrieveTransactionDetails":"********","theme":"********","transactionDetails":"********","timestamp":"********","address":"********","openInExplorer":"********","na":"********"}
|
|
@ -0,0 +1,8 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
|
@ -5,6 +5,8 @@ import 'package:path/path.dart';
|
|||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:warp_api/warp_api.dart';
|
||||
import 'package:splashscreen/splashscreen.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
import 'account.dart';
|
||||
import 'account_manager.dart';
|
||||
|
@ -51,6 +53,13 @@ void main() {
|
|||
theme: settings.themeData,
|
||||
home: home,
|
||||
scaffoldMessengerKey: rootScaffoldMessengerKey,
|
||||
localizationsDelegates: [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
onGenerateRoute: (RouteSettings settings) {
|
||||
var routes = <String, WidgetBuilder>{
|
||||
'/account': (context) => AccountPage(),
|
||||
|
@ -115,7 +124,7 @@ List<ElevatedButton> confirmButtons(BuildContext context, VoidCallback onPressed
|
|||
return <ElevatedButton>[
|
||||
ElevatedButton.icon(
|
||||
icon: Icon(Icons.cancel),
|
||||
label: Text('Cancel'),
|
||||
label: Text(S.of(context).cancel),
|
||||
onPressed: () {
|
||||
cancelValue != null ? navigator.pop(cancelValue) : navigator.pop();
|
||||
},
|
||||
|
@ -127,7 +136,7 @@ List<ElevatedButton> confirmButtons(BuildContext context, VoidCallback onPressed
|
|||
),
|
||||
ElevatedButton.icon(
|
||||
icon: okIcon ?? Icon(Icons.done),
|
||||
label: Text(okLabel ?? 'OK'),
|
||||
label: Text(okLabel ?? S.of(context).ok),
|
||||
onPressed: onPressed,
|
||||
)
|
||||
];
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:warp/store.dart';
|
|||
import 'package:warp_api/warp_api.dart';
|
||||
|
||||
import 'main.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
class MultiPayPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -17,12 +18,10 @@ class MultiPayPage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class MultiPayState extends State<MultiPayPage> {
|
||||
final _formKey = GlobalKey();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Multi Pay')),
|
||||
appBar: AppBar(title: Text(S.of(context).multiPay)),
|
||||
body: Observer(builder: (context) {
|
||||
final rows = multipayData.recipients.asMap().entries.map((e) {
|
||||
final index = e.key;
|
||||
|
@ -75,22 +74,22 @@ class MultiPayState extends State<MultiPayPage> {
|
|||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text('Please Confirm'),
|
||||
title: Text(S.of(context).pleaseConfirm),
|
||||
content: SingleChildScrollView(
|
||||
child: Text(
|
||||
"Sending a total of $amount ${coin.ticker} to $count recipients")),
|
||||
S.of(context).sendingATotalOfAmountCointickerToCountRecipients(amount, coin.ticker, count))),
|
||||
actions:
|
||||
confirmButtons(context, () => Navigator.of(context).pop(true), cancelValue: false)
|
||||
));
|
||||
|
||||
if (approved) {
|
||||
final snackBar1 = SnackBar(content: Text("Preparing transaction..."));
|
||||
final snackBar1 = SnackBar(content: Text(S.of(context).preparingTransaction));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar1);
|
||||
|
||||
final recipientsJson = jsonEncode(multipayData.recipients);
|
||||
final tx = await WarpApi.sendMultiPayment(accountManager.active.id,
|
||||
recipientsJson, settings.anchorOffset, (p) {});
|
||||
final snackBar2 = SnackBar(content: Text("TX ID: $tx"));
|
||||
final snackBar2 = SnackBar(content: Text(S.of(context).txId + tx));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar2);
|
||||
|
||||
multipayData.clear();
|
||||
|
@ -122,7 +121,7 @@ class PayRecipientState extends State<PayRecipient> {
|
|||
Row(children: <Widget>[
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(labelText: 'Send ${coin.ticker} to...'),
|
||||
decoration: InputDecoration(labelText: S.of(context).sendCointickerTo(coin.ticker)),
|
||||
minLines: 4,
|
||||
maxLines: null,
|
||||
keyboardType: TextInputType.multiline,
|
||||
|
@ -134,12 +133,12 @@ class PayRecipientState extends State<PayRecipient> {
|
|||
icon: new Icon(MdiIcons.qrcodeScan), onPressed: _onScan)
|
||||
]),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: 'Amount'),
|
||||
decoration: InputDecoration(labelText: S.of(context).amount),
|
||||
keyboardType: TextInputType.number,
|
||||
controller: _currencyController,
|
||||
validator: _checkAmount),
|
||||
ButtonBar(children:
|
||||
confirmButtons(context, _onAdd, okLabel: 'ADD', okIcon: Icon(MdiIcons.plus)))
|
||||
confirmButtons(context, _onAdd, okLabel: S.of(context).add, okIcon: Icon(MdiIcons.plus)))
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
@ -169,15 +168,15 @@ class PayRecipientState extends State<PayRecipient> {
|
|||
}
|
||||
|
||||
String _checkAddress(String v) {
|
||||
if (v.isEmpty) return 'Address is empty';
|
||||
if (!WarpApi.validAddress(v)) return 'Invalid Address';
|
||||
if (v.isEmpty) return S.of(context).addressIsEmpty;
|
||||
if (!WarpApi.validAddress(v)) return S.of(context).invalidAddress;
|
||||
return null;
|
||||
}
|
||||
|
||||
String _checkAmount(String vs) {
|
||||
final v = double.tryParse(vs);
|
||||
if (v == null) return 'Amount must be a number';
|
||||
if (v <= 0.0) return 'Amount must be positive';
|
||||
if (v == null) return S.of(context).amountMustBeANumber;
|
||||
if (v <= 0.0) return S.of(context).amountMustBePositive;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:warp_api/warp_api.dart';
|
|||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
import 'main.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
class RestorePage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -29,26 +30,22 @@ class _RestorePageState extends State<RestorePage> {
|
|||
padding: EdgeInsets.all(8),
|
||||
child: Column(children: [
|
||||
TextFormField(
|
||||
decoration: InputDecoration(labelText: 'Account Name'),
|
||||
decoration: InputDecoration(labelText: S.of(context).accountName),
|
||||
controller: _nameController,
|
||||
validator: (String name) {
|
||||
if (name == null || name.isEmpty)
|
||||
return "Account name is required";
|
||||
return S.of(context).accountNameIsRequired;
|
||||
return null;
|
||||
},
|
||||
),
|
||||
Row(
|
||||
// padding: EdgeInsets.all(8),
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(width: 2.0),
|
||||
// ),
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Key',
|
||||
labelText: S.of(context).key,
|
||||
hintText:
|
||||
'Enter Seed, Secret Key or Viewing Key. Leave blank for a new account'),
|
||||
S.of(context).enterSeed),
|
||||
minLines: 4,
|
||||
maxLines: 4,
|
||||
controller: _keyController,
|
||||
|
@ -59,7 +56,7 @@ class _RestorePageState extends State<RestorePage> {
|
|||
],
|
||||
),
|
||||
ButtonBar(children:
|
||||
confirmButtons(context, _validKey ? _onOK : null, okLabel: 'ADD', okIcon: Icon(Icons.add)))
|
||||
confirmButtons(context, _validKey ? _onOK : null, okLabel: S.of(context).add, okIcon: Icon(Icons.add)))
|
||||
]))));
|
||||
}
|
||||
|
||||
|
@ -73,7 +70,7 @@ class _RestorePageState extends State<RestorePage> {
|
|||
if (_keyController.text == "")
|
||||
WarpApi.skipToLastHeight(); // single new account -> quick sync
|
||||
else {
|
||||
final snackBar = SnackBar(content: Text("Scan starting momentarily"));
|
||||
final snackBar = SnackBar(content: Text(S.of(context).scanStartingMomentarily));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar);
|
||||
WarpApi.rewindToHeight(0);
|
||||
}
|
||||
|
@ -83,10 +80,6 @@ class _RestorePageState extends State<RestorePage> {
|
|||
}
|
||||
}
|
||||
|
||||
_onCancel() {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
_checkKey(key) {
|
||||
setState(() {
|
||||
_validKey = key == "" || WarpApi.validKey(key);
|
||||
|
|
|
@ -15,6 +15,7 @@ import 'dart:math' as math;
|
|||
|
||||
import 'main.dart';
|
||||
import 'store.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
class SendPage extends StatefulWidget {
|
||||
final Contact contact;
|
||||
|
@ -71,7 +72,7 @@ class SendState extends State<SendPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Send ${coin.ticker}')),
|
||||
appBar: AppBar(title: Text(S.of(context).sendCointicker(coin.ticker))),
|
||||
body: Form(
|
||||
key: _formKey,
|
||||
child: SingleChildScrollView(
|
||||
|
@ -81,7 +82,7 @@ class SendState extends State<SendPage> {
|
|||
Expanded(
|
||||
child: TextFormField(
|
||||
decoration:
|
||||
InputDecoration(labelText: 'Send ${coin.ticker} to...'),
|
||||
InputDecoration(labelText: S.of(context).sendCointickerTo(coin.ticker)),
|
||||
minLines: 4,
|
||||
maxLines: null,
|
||||
keyboardType: TextInputType.multiline,
|
||||
|
@ -103,7 +104,7 @@ class SendState extends State<SendPage> {
|
|||
validator: _checkAmount,
|
||||
onChanged: (_) { _updateOtherAmount(); },
|
||||
onSaved: _onAmount)),
|
||||
TextButton(child: Text('MAX'), onPressed: _onMax),
|
||||
TextButton(child: Text(S.of(context).max), onPressed: _onMax),
|
||||
]),
|
||||
Row(children: [
|
||||
Expanded(
|
||||
|
@ -124,32 +125,32 @@ class SendState extends State<SendPage> {
|
|||
children: [
|
||||
ExpansionPanel(
|
||||
headerBuilder: (_, __) =>
|
||||
ListTile(title: Text('Advanced Options')),
|
||||
ListTile(title: Text(S.of(context).advancedOptions)),
|
||||
body: Column(children: [
|
||||
ListTile(
|
||||
title: TextFormField(
|
||||
decoration: InputDecoration(labelText: 'Memo'),
|
||||
decoration: InputDecoration(labelText: S.of(context).memo),
|
||||
minLines: 4,
|
||||
maxLines: null,
|
||||
keyboardType: TextInputType.multiline,
|
||||
controller: _memoController,
|
||||
)),
|
||||
CheckboxListTile(
|
||||
title: Text('Round to millis'),
|
||||
title: Text(S.of(context).roundToMillis),
|
||||
value: _mZEC,
|
||||
onChanged: _onChangedmZEC),
|
||||
Observer(builder: (context) => CheckboxListTile(
|
||||
title: Text('Use ${settings.currency}'),
|
||||
title: Text(S.of(context).useSettingscurrency(settings.currency)),
|
||||
value: _useFX,
|
||||
onChanged: _onChangedUseFX)),
|
||||
CheckboxListTile(
|
||||
title: Text('Include Fee in Amount'),
|
||||
title: Text(S.of(context).includeFeeInAmount),
|
||||
value: _includeFee,
|
||||
onChanged: _onChangedIncludeFee),
|
||||
ListTile(
|
||||
title: TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Max Amount per Note'),
|
||||
labelText: S.of(context).maxAmountPerNote),
|
||||
keyboardType: TextInputType.number,
|
||||
controller: _maxAmountPerNoteController,
|
||||
validator: _checkMaxAmountPerNote,
|
||||
|
@ -159,31 +160,31 @@ class SendState extends State<SendPage> {
|
|||
isExpanded: _isExpanded)
|
||||
]),
|
||||
Padding(padding: EdgeInsets.all(8)),
|
||||
Text("Spendable: ${_balance / ZECUNIT} ${coin.ticker}"),
|
||||
Text(S.of(context).spendable + '${_balance / ZECUNIT} ${coin.ticker}'),
|
||||
ButtonBar(
|
||||
children: confirmButtons(context, _onSend, okLabel: 'SEND', okIcon: Icon(MdiIcons.send)))
|
||||
children: confirmButtons(context, _onSend, okLabel: S.of(context).send, okIcon: Icon(MdiIcons.send)))
|
||||
]))));
|
||||
}
|
||||
|
||||
String _checkAddress(String v) {
|
||||
if (v.isEmpty) return 'Address is empty';
|
||||
if (!WarpApi.validAddress(v)) return 'Invalid Address';
|
||||
if (v.isEmpty) return S.of(context).addressIsEmpty;
|
||||
if (!WarpApi.validAddress(v)) return S.of(context).invalidAddress;
|
||||
return null;
|
||||
}
|
||||
|
||||
String _checkAmount(String vs) {
|
||||
final vss = vs.replaceAll(',', '');
|
||||
final v = double.tryParse(vss);
|
||||
if (v == null) return 'Amount must be a number';
|
||||
if (v <= 0.0) return 'Amount must be positive';
|
||||
if (amountInZAT(Decimal.parse(vss)) > _balance) return 'Not enough balance';
|
||||
if (v == null) return S.of(context).amountMustBeANumber;
|
||||
if (v <= 0.0) return S.of(context).amountMustBePositive;
|
||||
if (amountInZAT(Decimal.parse(vss)) > _balance) return S.of(context).notEnoughBalance;
|
||||
return null;
|
||||
}
|
||||
|
||||
String _checkMaxAmountPerNote(String vs) {
|
||||
final v = double.tryParse(vs);
|
||||
if (v == null) return 'Amount must be a number';
|
||||
if (v < 0.0) return 'Amount must be positive';
|
||||
if (v == null) return S.of(context).amountMustBeANumber;
|
||||
if (v < 0.0) return S.of(context).amountMustBePositive;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -263,14 +264,14 @@ class SendState extends State<SendPage> {
|
|||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: Text('Please Confirm'),
|
||||
title: Text(S.of(context).pleaseConfirm),
|
||||
content: SingleChildScrollView(
|
||||
child: Text("Sending $aZEC ${coin.ticker} to $_address")),
|
||||
actions: confirmButtons(context, () => Navigator.of(context).pop(true), okLabel: 'APPROVE', cancelValue: false)
|
||||
child: Text(S.of(context).sendingAzecCointickerToAddress(aZEC, coin.ticker, _address))),
|
||||
actions: confirmButtons(context, () => Navigator.of(context).pop(true), okLabel: S.of(context).approve, cancelValue: false)
|
||||
));
|
||||
if (approved) {
|
||||
Navigator.of(context).pop();
|
||||
final snackBar1 = SnackBar(content: Text("Preparing transaction..."));
|
||||
final snackBar1 = SnackBar(content: Text(S.of(context).preparingTransaction));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar1);
|
||||
|
||||
if (_includeFee) _amount -= DEFAULT_FEE;
|
||||
|
@ -289,7 +290,7 @@ class SendState extends State<SendPage> {
|
|||
settings.anchorOffset,
|
||||
progressPort.sendPort));
|
||||
|
||||
final snackBar2 = SnackBar(content: Text("TX ID: $tx"));
|
||||
final snackBar2 = SnackBar(content: Text(S.of(context).txId + tx));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar2);
|
||||
} else {
|
||||
Directory tempDir = await getTemporaryDirectory();
|
||||
|
@ -298,7 +299,7 @@ class SendState extends State<SendPage> {
|
|||
final msg = WarpApi.prepareTx(accountManager.active.id, _address, _amount, memo,
|
||||
maxAmountPerNote, settings.anchorOffset, filename);
|
||||
|
||||
Share.shareFiles([filename], subject: "Unsigned Transaction File");
|
||||
Share.shareFiles([filename], subject: S.of(context).unsignedTransactionFile);
|
||||
|
||||
final snackBar2 = SnackBar(content: Text(msg));
|
||||
rootScaffoldMessengerKey.currentState.showSnackBar(snackBar2);
|
||||
|
@ -313,9 +314,9 @@ class SendState extends State<SendPage> {
|
|||
thousandSeparator: ',',
|
||||
precision: mZEC ? 3 : 8);
|
||||
|
||||
String thisAmountLabel() => _useFX ? "Amount in ${settings.currency}" : "Amount in ${coin.ticker}";
|
||||
String thisAmountLabel() => S.of(context).amountInSettingscurrency(_useFX ? settings.currency : coin.ticker);
|
||||
|
||||
String otherAmountLabel() => _useFX ? "Amount in ${coin.ticker}" : "Amount in ${settings.currency}";
|
||||
String otherAmountLabel() => S.of(context).amountInSettingscurrency(_useFX ? coin.ticker : settings.currency);
|
||||
|
||||
int amountInZAT(Decimal v) => _useFX
|
||||
? (v / _fx() * ZECUNIT_DECIMAL).toInt()
|
||||
|
|
|
@ -3,8 +3,8 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
|
|||
import 'package:flutter_masked_text/flutter_masked_text.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
import 'account.dart';
|
||||
import 'main.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
class SettingsPage extends StatefulWidget {
|
||||
@override
|
||||
|
@ -29,14 +29,14 @@ class SettingsState extends State<SettingsPage> {
|
|||
value: 'custom',
|
||||
child: FormBuilderTextField(
|
||||
decoration:
|
||||
InputDecoration(labelText: 'Custom'),
|
||||
InputDecoration(labelText: S.of(context).custom),
|
||||
initialValue: settings.ldUrl,
|
||||
onSaved: _onURL,
|
||||
)),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Settings')),
|
||||
appBar: AppBar(title: Text(S.of(context).settings)),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: FormBuilder(
|
||||
|
@ -46,25 +46,25 @@ class SettingsState extends State<SettingsPage> {
|
|||
FormBuilderRadioGroup(
|
||||
orientation: OptionsOrientation.vertical,
|
||||
name: 'servers',
|
||||
decoration: InputDecoration(labelText: 'Server'),
|
||||
decoration: InputDecoration(labelText: S.of(context).server),
|
||||
initialValue: settings.ldUrlChoice,
|
||||
onSaved: _onChoice,
|
||||
options: options),
|
||||
FormBuilderRadioGroup(
|
||||
orientation: OptionsOrientation.horizontal,
|
||||
name: 'themes',
|
||||
decoration: InputDecoration(labelText: 'Theme'),
|
||||
decoration: InputDecoration(labelText: S.of(context).theme),
|
||||
initialValue: settings.theme,
|
||||
onChanged: _onTheme,
|
||||
options: [
|
||||
FormBuilderFieldOption(
|
||||
child: Text('Zcash'), value: 'zcash'),
|
||||
FormBuilderFieldOption(
|
||||
child: Text('Blue'), value: 'blue'),
|
||||
child: Text(S.of(context).blue), value: 'blue'),
|
||||
FormBuilderFieldOption(
|
||||
child: Text('Pink'), value: 'pink'),
|
||||
child: Text(S.of(context).pink), value: 'pink'),
|
||||
FormBuilderFieldOption(
|
||||
child: Text('Coffee'), value: 'coffee'),
|
||||
child: Text(S.of(context).coffee), value: 'coffee'),
|
||||
]),
|
||||
FormBuilderRadioGroup(
|
||||
orientation: OptionsOrientation.horizontal,
|
||||
|
@ -73,13 +73,13 @@ class SettingsState extends State<SettingsPage> {
|
|||
onChanged: _onThemeBrightness,
|
||||
options: [
|
||||
FormBuilderFieldOption(
|
||||
child: Text('Light'), value: 'light'),
|
||||
child: Text(S.of(context).light), value: 'light'),
|
||||
FormBuilderFieldOption(
|
||||
child: Text('Dark'), value: 'dark'),
|
||||
child: Text(S.of(context).dark), value: 'dark'),
|
||||
]),
|
||||
Row(children: [
|
||||
SizedBox(width: 100, child: DropdownButtonFormField<String>(
|
||||
decoration: InputDecoration(labelText: 'Currency'),
|
||||
decoration: InputDecoration(labelText: S.of(context).currency),
|
||||
value: settings.currency,
|
||||
items: settings.currencies.map((c) =>
|
||||
DropdownMenuItem(child: Text(c), value: c)).toList(),
|
||||
|
@ -89,14 +89,14 @@ class SettingsState extends State<SettingsPage> {
|
|||
FormBuilderTextField(
|
||||
decoration: InputDecoration(
|
||||
labelText:
|
||||
'Number of Confirmations Needed before Spending'),
|
||||
S.of(context).numberOfConfirmationsNeededBeforeSpending),
|
||||
name: 'anchor',
|
||||
keyboardType: TextInputType.number,
|
||||
controller: _anchorController,
|
||||
onSaved: _onAnchorOffset),
|
||||
FormBuilderCheckbox(
|
||||
name: 'get_tx',
|
||||
title: Text('Retrieve Transaction Details'),
|
||||
title: Text(S.of(context).retrieveTransactionDetails),
|
||||
initialValue: settings.getTx,
|
||||
onSaved: _onGetTx),
|
||||
ButtonBar(children:
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:url_launcher/url_launcher.dart';
|
|||
|
||||
import 'main.dart';
|
||||
import 'store.dart';
|
||||
import 'generated/l10n.dart';
|
||||
|
||||
class TransactionPage extends StatefulWidget {
|
||||
final Tx tx;
|
||||
|
@ -18,20 +19,20 @@ class TransactionState extends State<TransactionPage> {
|
|||
Widget build(BuildContext context) {
|
||||
final textTheme = Theme.of(context).textTheme;
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Transaction Details')),
|
||||
appBar: AppBar(title: Text(S.of(context).transactionDetails)),
|
||||
body: ListView(padding: EdgeInsets.all(16), children: [
|
||||
ListTile(
|
||||
title: Text('TXID'), subtitle: SelectableText('${widget.tx.fullTxId}')),
|
||||
title: Text(S.of(context).txid), subtitle: SelectableText('${widget.tx.fullTxId}')),
|
||||
ListTile(
|
||||
title: Text('Height'), subtitle: SelectableText('${widget.tx.height}')),
|
||||
title: Text(S.of(context).height), subtitle: SelectableText('${widget.tx.height}')),
|
||||
ListTile(
|
||||
title: Text('Timestamp'),
|
||||
title: Text(S.of(context).timestamp),
|
||||
subtitle: Text('${widget.tx.timestamp}')),
|
||||
ListTile(title: Text('Amount'), subtitle: SelectableText('${widget.tx.value.toStringAsFixed(8)}')),
|
||||
ListTile(title: Text(S.of(context).amount), subtitle: SelectableText('${widget.tx.value.toStringAsFixed(8)}')),
|
||||
ListTile(
|
||||
title: Text('Address'), subtitle: SelectableText('${widget.tx.address ?? "N/A"}')),
|
||||
ListTile(title: Text('Memo'), subtitle: SelectableText('${widget.tx.memo ?? "N/A"}')),
|
||||
ElevatedButton(onPressed: _onOpen, child: Text('Open in Explorer'))
|
||||
title: Text(S.of(context).address), subtitle: SelectableText('${widget.tx.address ?? S.of(context).na}')),
|
||||
ListTile(title: Text(S.of(context).memo), subtitle: SelectableText('${widget.tx.memo ?? S.of(context).na}')),
|
||||
ElevatedButton(onPressed: _onOpen, child: Text(S.of(context).openInExplorer))
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ packages:
|
|||
source: hosted
|
||||
version: "0.0.1"
|
||||
flutter_localizations:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
|
|
|
@ -53,6 +53,8 @@ dependencies:
|
|||
path_provider: any
|
||||
file_picker: any
|
||||
mustache_template: any
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
|
@ -117,3 +119,5 @@ flutter:
|
|||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# see https://flutter.dev/custom-fonts/#from-packages
|
||||
flutter_intl:
|
||||
enabled: true
|
||||
|
|
Loading…
Reference in New Issue