mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-22 18:54:47 +00:00
receive pt.2
This commit is contained in:
parent
d309e528f6
commit
3d65ccffa2
10 changed files with 379 additions and 341 deletions
BIN
assets/images/warning.png
Normal file
BIN
assets/images/warning.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 926 B |
|
@ -23,6 +23,8 @@ part 'lightning_wallet.g.dart';
|
|||
class LightningWallet = LightningWalletBase with _$LightningWallet;
|
||||
|
||||
abstract class LightningWalletBase extends ElectrumWallet with Store {
|
||||
int satBalance = 0;
|
||||
|
||||
LightningWalletBase(
|
||||
{required String mnemonic,
|
||||
required String password,
|
||||
|
@ -128,6 +130,18 @@ abstract class LightningWalletBase extends ElectrumWallet with Store {
|
|||
breezConfig = breezConfig.copyWith(workingDir: workingDir);
|
||||
await sdk.connect(config: breezConfig, seed: seedBytes);
|
||||
|
||||
print("initialized: ${(await sdk.isInitialized())}");
|
||||
sdk.nodeStateStream.listen((event) {
|
||||
// print("Node state: $event");
|
||||
if (event == null) return;
|
||||
// int balanceSat = event.maxPayableMsat ~/ 1000;
|
||||
// print("sats: $balanceSat");
|
||||
balance[CryptoCurrency.btc] = ElectrumBalance(
|
||||
confirmed: event.maxPayableMsat,
|
||||
unconfirmed: event.maxReceivableMsat,
|
||||
frozen: 0,
|
||||
);
|
||||
});
|
||||
|
||||
print("initialized breez: ${(await sdk.isInitialized())}");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1200,10 +1200,8 @@ Future<void> setup({
|
|||
getIt.registerFactory<TorPage>(() => TorPage(getIt.get<AppStore>()));
|
||||
|
||||
getIt.registerFactoryParam<LightningInvoicePageViewModel, List<dynamic>, void>((args, _) {
|
||||
final address = args.first as String;
|
||||
final pageOption = args.last as ReceivePageOption;
|
||||
final pageOption = args.first as ReceivePageOption;
|
||||
return LightningInvoicePageViewModel(
|
||||
address,
|
||||
getIt.get<SettingsStore>(),
|
||||
getIt.get<AppStore>().wallet!,
|
||||
getIt.get<SharedPreferences>(),
|
||||
|
@ -1222,7 +1220,7 @@ Future<void> setup({
|
|||
final pageOption = args.last as ReceivePageOption;
|
||||
return LightningReceiveOnchainPage(
|
||||
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
|
||||
// lightningViewModel: LightningViewModel(),
|
||||
lightningViewModel: LightningViewModel(),
|
||||
receiveOptionViewModel: getIt.get<ReceiveOptionViewModel>(param1: pageOption));
|
||||
});
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class MainActions {
|
|||
Navigator.pushNamed(
|
||||
context,
|
||||
Routes.lightningInvoice,
|
||||
arguments: [viewModel.address, ReceivePageOption.lightningInvoice],
|
||||
arguments: [ReceivePageOption.lightningInvoice],
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ enum ReceivePageOption {
|
|||
label = 'Trocador AnonPay Donation Link';
|
||||
break;
|
||||
case ReceivePageOption.lightningInvoice:
|
||||
label = 'Sats via Invoice';
|
||||
label = 'Lightning via Invoice';
|
||||
break;
|
||||
case ReceivePageOption.lightningOnchain:
|
||||
label = 'Sats via BTC address';
|
||||
label = 'Lightning via BTC address';
|
||||
break;
|
||||
}
|
||||
return label;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cake_wallet/src/screens/receive/widgets/lightning_input_form.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
|
||||
|
@ -151,11 +152,46 @@ class LightningInvoicePage extends BasePage {
|
|||
// ),
|
||||
// ),
|
||||
// ),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 12, bottom: 12, right: 6),
|
||||
margin: const EdgeInsets.only(left: 24, right: 24, bottom: 48),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
color: Color.fromARGB(94, 255, 221, 44),
|
||||
border: Border.all(
|
||||
color: Color.fromARGB(178, 223, 214, 0),
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
margin: EdgeInsets.only(left: 12, bottom: 48, right: 12),
|
||||
child: Image.asset("assets/images/warning.png"),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"A setup fee of 0.4% with a minimum of 2,079 sats will be applied upon receiving this invoice.",
|
||||
maxLines: 3,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
LoadingPrimaryButton(
|
||||
text: S.of(context).create_invoice,
|
||||
onPressed: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
lightningViewModel.createInvoice(amount: _amountController.text, description: _descriptionController.text);
|
||||
lightningViewModel.createInvoice(
|
||||
amount: _amountController.text, description: _descriptionController.text);
|
||||
lightningInvoicePageViewModel.setRequestParams(
|
||||
inputAmount: _amountController.text,
|
||||
inputDescription: _descriptionController.text,
|
||||
|
@ -185,14 +221,14 @@ class LightningInvoicePage extends BasePage {
|
|||
case ReceivePageOption.lightningInvoice:
|
||||
break;
|
||||
case ReceivePageOption.lightningOnchain:
|
||||
final address = await lightningViewModel.receiveOnchain();
|
||||
Navigator.popAndPushNamed(
|
||||
context,
|
||||
Routes.lightningReceiveOnchain,
|
||||
arguments: [address, ReceivePageOption.lightningInvoice],
|
||||
arguments: [ReceivePageOption.lightningOnchain],
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
import 'package:cake_wallet/entities/qr_view_data.dart';
|
||||
import 'package:cake_wallet/entities/receive_page_option.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
|
||||
import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
|
||||
import 'package:cake_wallet/src/widgets/gradient_background.dart';
|
||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
|
||||
import 'package:cake_wallet/utils/brightness_util.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/lightning_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class LightningReceiveOnchainPage extends BasePage {
|
||||
LightningReceiveOnchainPage({required this.addressListViewModel, required this.receiveOptionViewModel})
|
||||
: _cryptoAmountFocus = FocusNode(),
|
||||
_amountController = TextEditingController(),
|
||||
LightningReceiveOnchainPage(
|
||||
{required this.addressListViewModel,
|
||||
required this.receiveOptionViewModel,
|
||||
required this.lightningViewModel})
|
||||
: _amountController = TextEditingController(),
|
||||
_formKey = GlobalKey<FormState>() {
|
||||
_amountController.addListener(() {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
|
@ -20,9 +34,11 @@ class LightningReceiveOnchainPage extends BasePage {
|
|||
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
final ReceiveOptionViewModel receiveOptionViewModel;
|
||||
final LightningViewModel lightningViewModel;
|
||||
final TextEditingController _amountController;
|
||||
final GlobalKey<FormState> _formKey;
|
||||
static const _heroTag = 'receive_page';
|
||||
|
||||
bool effectsInstalled = false;
|
||||
|
||||
@override
|
||||
String get title => S.current.receive;
|
||||
|
@ -33,20 +49,6 @@ class LightningReceiveOnchainPage extends BasePage {
|
|||
@override
|
||||
bool get resizeToAvoidBottomInset => true;
|
||||
|
||||
final FocusNode _cryptoAmountFocus;
|
||||
|
||||
// @override
|
||||
// Widget middle(BuildContext context) {
|
||||
// return Text(
|
||||
// title,
|
||||
// style: TextStyle(
|
||||
// fontSize: 18.0,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontFamily: 'Lato',
|
||||
// color: pageIconColor(context)),
|
||||
// );
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) => PresentReceiveOptionPicker(
|
||||
color: titleColor(context), receiveOptionViewModel: receiveOptionViewModel);
|
||||
|
@ -57,6 +59,186 @@ class LightningReceiveOnchainPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return SizedBox();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _setReactions(context));
|
||||
final copyImage = Image.asset('assets/images/copy_address.png',
|
||||
color: Theme.of(context).extension<QRCodeTheme>()!.qrWidgetCopyButtonColor);
|
||||
String heroTag = "lightning_receive";
|
||||
return Center(
|
||||
child: Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
FutureBuilder(
|
||||
future: lightningViewModel.receiveOnchain(),
|
||||
builder: ((context, snapshot) {
|
||||
if (snapshot.data == null) {
|
||||
return CircularProgressIndicator();
|
||||
}
|
||||
String data = (snapshot.data as List<String>)[0];
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: Text(
|
||||
S.of(context).qr_fullscreen,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Spacer(flex: 3),
|
||||
Observer(
|
||||
builder: (_) => Flexible(
|
||||
flex: 5,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
BrightnessUtil.changeBrightnessForFunction(
|
||||
() async {
|
||||
await Navigator.pushNamed(context, Routes.fullscreenQR,
|
||||
arguments: QrViewData(
|
||||
data: data,
|
||||
heroTag: heroTag,
|
||||
));
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Hero(
|
||||
tag: Key(heroTag),
|
||||
child: Center(
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1.0,
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 3,
|
||||
color: Theme.of(context)
|
||||
.extension<DashboardPageTheme>()!
|
||||
.textColor,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 3,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
child: QrImage(data: data)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(flex: 3)
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 8, left: 24, right: 24),
|
||||
child: Builder(
|
||||
builder: (context) => Observer(
|
||||
builder: (context) => GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: data));
|
||||
showBar<void>(context, S.of(context).copied_to_clipboard);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Text(
|
||||
addressListViewModel.address.address,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.extension<DashboardPageTheme>()!
|
||||
.textColor),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 12),
|
||||
child: copyImage,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(top: 24, bottom: 24, right: 6),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
color: Color.fromARGB(94, 255, 221, 44),
|
||||
border: Border.all(
|
||||
color: Color.fromARGB(178, 223, 214, 0),
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
margin: EdgeInsets.only(left: 12, bottom: 48, right: 12),
|
||||
child: Image.asset("assets/images/warning.png"),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Send more than 20,029 sats and up to 3,998,387 sats to this address. A setup fee of 0.4% with a minimum of 2,079 sats will be applied upon receiving this invoice. This will convert any received Bitcoin into Lightning. An on-chain fee will be applied. This address can only be used once.",
|
||||
maxLines: 10,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _setReactions(BuildContext context) {
|
||||
if (effectsInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
reaction((_) => receiveOptionViewModel.selectedReceiveOption, (ReceivePageOption option) async {
|
||||
switch (option) {
|
||||
case ReceivePageOption.lightningInvoice:
|
||||
Navigator.popAndPushNamed(
|
||||
context,
|
||||
Routes.lightningInvoice,
|
||||
arguments: [ReceivePageOption.lightningInvoice],
|
||||
);
|
||||
break;
|
||||
case ReceivePageOption.lightningOnchain:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
effectsInstalled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,12 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.da
|
|||
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/add_template_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/seed_widget_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
|
@ -16,6 +20,7 @@ import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
|||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/view_model/send/send_view_model.dart';
|
||||
|
@ -45,6 +50,9 @@ class LightningSendPage extends BasePage {
|
|||
final controller = PageController(initialPage: 0);
|
||||
final PaymentRequest? initialPaymentRequest;
|
||||
|
||||
final bolt11Controller = TextEditingController();
|
||||
final _bolt11FocusNode = FocusNode();
|
||||
|
||||
bool _effectsInstalled = false;
|
||||
|
||||
@override
|
||||
|
@ -133,18 +141,16 @@ class LightningSendPage extends BasePage {
|
|||
? TrailButton(
|
||||
caption: S.of(context).remove,
|
||||
onPressed: () {
|
||||
var pageToJump = (controller.page?.round() ?? 0) - 1;
|
||||
pageToJump = pageToJump > 0 ? pageToJump : 0;
|
||||
final output = _defineCurrentOutput();
|
||||
sendViewModel.removeOutput(output);
|
||||
controller.jumpToPage(pageToJump);
|
||||
// var pageToJump = (controller.page?.round() ?? 0) - 1;
|
||||
// pageToJump = pageToJump > 0 ? pageToJump : 0;
|
||||
// final output = _defineCurrentOutput();
|
||||
// sendViewModel.removeOutput(output);
|
||||
// controller.jumpToPage(pageToJump);
|
||||
})
|
||||
: TrailButton(
|
||||
caption: S.of(context).clear,
|
||||
onPressed: () {
|
||||
final output = _defineCurrentOutput();
|
||||
_formKey.currentState?.reset();
|
||||
output.reset();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -152,242 +158,117 @@ class LightningSendPage extends BasePage {
|
|||
Widget body(BuildContext context) {
|
||||
_setEffects(context);
|
||||
|
||||
return GestureDetector(
|
||||
onLongPress: () =>
|
||||
sendViewModel.balanceViewModel.isReversing = !sendViewModel.balanceViewModel.isReversing,
|
||||
onLongPressUp: () =>
|
||||
sendViewModel.balanceViewModel.isReversing = !sendViewModel.balanceViewModel.isReversing,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
return WillPopScope(
|
||||
onWillPop: () => _onNavigateBack(context),
|
||||
child: KeyboardActions(
|
||||
disableScroll: true,
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
focusNode: FocusNode(),
|
||||
// focusNode: _amountFocusNode,
|
||||
toolbarButtons: [(_) => KeyboardDoneButton()],
|
||||
),
|
||||
]),
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(bottom: 24),
|
||||
content: FocusTraversalGroup(
|
||||
policy: OrderedTraversalPolicy(),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: _sendCardHeight(context),
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
return PageView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: controller,
|
||||
itemCount: sendViewModel.outputs.length,
|
||||
itemBuilder: (context, index) {
|
||||
final output = sendViewModel.outputs[index];
|
||||
|
||||
return SendCard(
|
||||
key: output.key,
|
||||
output: output,
|
||||
sendViewModel: sendViewModel,
|
||||
initialPaymentRequest: initialPaymentRequest,
|
||||
);
|
||||
});
|
||||
},
|
||||
)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, left: 24, right: 24, bottom: 10),
|
||||
child: Container(
|
||||
height: 10,
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
final count = sendViewModel.outputs.length;
|
||||
|
||||
return count > 1
|
||||
? SmoothPageIndicator(
|
||||
controller: controller,
|
||||
count: count,
|
||||
effect: ScrollingDotsEffect(
|
||||
spacing: 6.0,
|
||||
radius: 6.0,
|
||||
dotWidth: 6.0,
|
||||
dotHeight: 6.0,
|
||||
dotColor: Theme.of(context)
|
||||
.extension<SendPageTheme>()!
|
||||
.indicatorDotColor,
|
||||
activeDotColor: Theme.of(context)
|
||||
.extension<SendPageTheme>()!
|
||||
.templateBackgroundColor),
|
||||
content: Container(
|
||||
decoration: responsiveLayoutUtil.shouldRenderMobileUI
|
||||
? BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.firstGradientTopPanelColor,
|
||||
Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.secondGradientTopPanelColor,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
)
|
||||
: Offstage();
|
||||
},
|
||||
: null,
|
||||
child: Observer(builder: (_) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
|
||||
child: BaseTextFormField(
|
||||
controller: bolt11Controller,
|
||||
focusNode: _bolt11FocusNode,
|
||||
textInputAction: TextInputAction.next,
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
hintText: S.of(context).invoice_details,
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
),
|
||||
textStyle:
|
||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
final templates = sendViewModel.templates;
|
||||
final itemCount = templates.length;
|
||||
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
AddTemplateButton(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.sendTemplate),
|
||||
currentTemplatesLength: templates.length,
|
||||
),
|
||||
ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: itemCount,
|
||||
itemBuilder: (context, index) {
|
||||
final template = templates[index];
|
||||
return TemplateTile(
|
||||
key: UniqueKey(),
|
||||
to: template.name,
|
||||
hasMultipleRecipients: template.additionalRecipients != null &&
|
||||
template.additionalRecipients!.length > 1,
|
||||
amount: template.isCurrencySelected
|
||||
? template.amount
|
||||
: template.amountFiat,
|
||||
from: template.isCurrencySelected
|
||||
? template.cryptoCurrency
|
||||
: template.fiatCurrency,
|
||||
onTap: () async {
|
||||
if (template.additionalRecipients?.isNotEmpty ?? false) {
|
||||
sendViewModel.clearOutputs();
|
||||
|
||||
for (int i = 0;
|
||||
i < template.additionalRecipients!.length;
|
||||
i++) {
|
||||
Output output;
|
||||
try {
|
||||
output = sendViewModel.outputs[i];
|
||||
} catch (e) {
|
||||
sendViewModel.addOutput();
|
||||
output = sendViewModel.outputs[i];
|
||||
}
|
||||
|
||||
await _setInputsFromTemplate(
|
||||
context,
|
||||
output: output,
|
||||
template: template.additionalRecipients![i],
|
||||
);
|
||||
}
|
||||
} else {
|
||||
final output = _defineCurrentOutput();
|
||||
await _setInputsFromTemplate(
|
||||
context,
|
||||
output: output,
|
||||
template: template,
|
||||
);
|
||||
}
|
||||
},
|
||||
onRemove: () {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (dialogContext) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context).template,
|
||||
alertContent: S.of(context).confirm_delete_template,
|
||||
rightButtonText: S.of(context).delete,
|
||||
leftButtonText: S.of(context).cancel,
|
||||
actionRightButton: () {
|
||||
Navigator.of(dialogContext).pop();
|
||||
sendViewModel.sendTemplateViewModel
|
||||
.removeTemplate(template: template);
|
||||
},
|
||||
actionLeftButton: () =>
|
||||
Navigator.of(dialogContext).pop());
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
}),
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: Column(
|
||||
children: [
|
||||
if (sendViewModel.hasCurrecyChanger)
|
||||
Observer(
|
||||
builder: (_) => Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () => presentCurrencyPicker(context),
|
||||
text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
|
||||
color: Colors.transparent,
|
||||
textColor:
|
||||
Theme.of(context).extension<SeedWidgetTheme>()!.hintTextColor,
|
||||
))),
|
||||
if (sendViewModel.sendTemplateViewModel.hasMultiRecipient)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () {
|
||||
sendViewModel.addOutput();
|
||||
Future.delayed(const Duration(milliseconds: 250), () {
|
||||
controller.jumpToPage(sendViewModel.outputs.length - 1);
|
||||
});
|
||||
},
|
||||
text: S.of(context).add_receiver,
|
||||
color: Colors.transparent,
|
||||
textColor: Theme.of(context).extension<SeedWidgetTheme>()!.hintTextColor,
|
||||
isDottedBorder: true,
|
||||
borderColor:
|
||||
Theme.of(context).extension<SendPageTheme>()!.templateDottedBorderColor,
|
||||
)),
|
||||
Observer(
|
||||
builder: (_) {
|
||||
return LoadingPrimaryButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
|
||||
if (sendViewModel.outputs.length > 1) {
|
||||
showErrorValidationAlert(context);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
final notValidItems = sendViewModel.outputs
|
||||
.where((item) => item.address.isEmpty || item.cryptoAmount.isEmpty)
|
||||
.toList();
|
||||
|
||||
if (notValidItems.isNotEmpty) {
|
||||
showErrorValidationAlert(context);
|
||||
return;
|
||||
}
|
||||
|
||||
final check = sendViewModel.shouldDisplayTotp();
|
||||
authService.authenticateAction(
|
||||
context,
|
||||
conditionToDetermineIfToUse2FA: check,
|
||||
onAuthSuccess: (value) async {
|
||||
if (value) {
|
||||
await sendViewModel.createTransaction();
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
bottomSection: Observer(builder: (_) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
// Padding(
|
||||
// padding: EdgeInsets.only(bottom: 15),
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// S.of(context).anonpay_description("an invoice", "pay"),
|
||||
// textAlign: TextAlign.center,
|
||||
// style: TextStyle(
|
||||
// color: Theme.of(context)
|
||||
// .extension<ExchangePageTheme>()!
|
||||
// .receiveAmountColor,
|
||||
// fontWeight: FontWeight.w500,
|
||||
// fontSize: 12),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
LoadingPrimaryButton(
|
||||
text: S.of(context).send,
|
||||
onPressed: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
// lightningViewModel.createInvoice(
|
||||
// amount: _amountController.text, description: _descriptionController.text);
|
||||
// lightningInvoicePageViewModel.setRequestParams(
|
||||
// inputAmount: _amountController.text,
|
||||
// inputDescription: _descriptionController.text,
|
||||
// );
|
||||
// lightningInvoicePageViewModel.createInvoice();
|
||||
},
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isLoading: sendViewModel.state is IsExecutingState ||
|
||||
sendViewModel.state is TransactionCommitting,
|
||||
isDisabled: !sendViewModel.isReadyForSend,
|
||||
);
|
||||
},
|
||||
)
|
||||
isLoading: false,
|
||||
),
|
||||
],
|
||||
)),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> _onNavigateBack(BuildContext context) async {
|
||||
onClose(context);
|
||||
return false;
|
||||
}
|
||||
|
||||
void _setEffects(BuildContext context) {
|
||||
if (_effectsInstalled) {
|
||||
return;
|
||||
|
@ -469,57 +350,4 @@ class LightningSendPage extends BasePage {
|
|||
|
||||
_effectsInstalled = true;
|
||||
}
|
||||
|
||||
Future<void> _setInputsFromTemplate(BuildContext context,
|
||||
{required Output output, required Template template}) async {
|
||||
output.address = template.address;
|
||||
|
||||
if (template.isCurrencySelected) {
|
||||
sendViewModel.setSelectedCryptoCurrency(template.cryptoCurrency);
|
||||
output.setCryptoAmount(template.amount);
|
||||
} else {
|
||||
final fiatFromTemplate =
|
||||
FiatCurrency.all.singleWhere((element) => element.title == template.fiatCurrency);
|
||||
|
||||
sendViewModel.setFiatCurrency(fiatFromTemplate);
|
||||
output.setFiatAmount(template.amountFiat);
|
||||
}
|
||||
|
||||
output.resetParsedAddress();
|
||||
await output.fetchParsedAddress(context);
|
||||
}
|
||||
|
||||
Output _defineCurrentOutput() {
|
||||
if (controller.page == null) {
|
||||
throw Exception('Controller page is null');
|
||||
}
|
||||
final itemCount = controller.page!.round();
|
||||
return sendViewModel.outputs[itemCount];
|
||||
}
|
||||
|
||||
void showErrorValidationAlert(BuildContext context) async {
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).error,
|
||||
alertContent: 'Please, check receiver forms',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
|
||||
void presentCurrencyPicker(BuildContext context) async {
|
||||
await showPopUp<CryptoCurrency>(
|
||||
builder: (_) => Picker(
|
||||
items: sendViewModel.currencies,
|
||||
displayItem: (Object item) => item.toString(),
|
||||
selectedAtIndex:
|
||||
sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
|
||||
title: S.of(context).please_select,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
onItemSelected: (CryptoCurrency cur) => sendViewModel.selectedCryptoCurrency = cur,
|
||||
),
|
||||
context: context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
import 'package:cake_wallet/anonpay/anonpay_api.dart';
|
||||
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
|
||||
import 'package:cake_wallet/anonpay/anonpay_request.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/entities/receive_page_option.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/view_model/lightning_view_model.dart';
|
||||
|
@ -11,7 +7,6 @@ import 'package:cw_core/crypto_currency.dart';
|
|||
import 'package:cw_core/currency.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
|
@ -22,7 +17,6 @@ class LightningInvoicePageViewModel = LightningInvoicePageViewModelBase
|
|||
|
||||
abstract class LightningInvoicePageViewModelBase with Store {
|
||||
LightningInvoicePageViewModelBase(
|
||||
this.address,
|
||||
this.settingsStore,
|
||||
this._wallet,
|
||||
this.sharedPreferences,
|
||||
|
@ -37,10 +31,8 @@ abstract class LightningInvoicePageViewModelBase with Store {
|
|||
}
|
||||
|
||||
List<Currency> get currencies => [walletTypeToCryptoCurrency(_wallet.type), ...FiatCurrency.all];
|
||||
final String address;
|
||||
final SettingsStore settingsStore;
|
||||
final WalletBase _wallet;
|
||||
// final Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
|
||||
final SharedPreferences sharedPreferences;
|
||||
final ReceivePageOption pageOption;
|
||||
final LightningViewModel lightningViewModel;
|
||||
|
@ -120,12 +112,8 @@ abstract class LightningInvoicePageViewModelBase with Store {
|
|||
|
||||
Future<void> _fetchLimits() async {
|
||||
List<String> limits = await lightningViewModel.invoiceLimits();
|
||||
// final limit = await anonPayApi.fetchLimits(
|
||||
// cryptoCurrency: cryptoCurrency,
|
||||
// fiatCurrency: selectedCurrency is FiatCurrency ? selectedCurrency as FiatCurrency : null,
|
||||
// );
|
||||
// minimum = limit.min;
|
||||
// maximum = limit.max != null ? limit.max! / 4 : null;
|
||||
minimum = double.tryParse(limits[0]);
|
||||
maximum = double.tryParse(limits[1]);
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'package:breez_sdk/breez_sdk.dart';
|
||||
import 'package:breez_sdk/bridge_generated.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/view_model/auth_state.dart';
|
||||
import 'package:cake_wallet/core/auth_service.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/entities/biometric_auth.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
|
||||
part 'lightning_view_model.g.dart';
|
||||
|
||||
|
|
Loading…
Reference in a new issue