Mweb enhancements 4 (#1768)

* [skip-ci] show mweb confirmations, show last mweb balance while syncing

* potential send-all fix

* [skip-ci] undo fix that didn't work

* [skip-ci] undo unnecessary changes

* [skip ci] add export mweb logs screen

* [skip ci] cleanup

* confirmation fixes

* catch electrum call errors

* [skip ci] undo some changes

* potential electrum fixes + mweb logs display only last 10000 characters

* Add question mark and link to MWEB card

* updates

* show negative unconfirmed mweb balanaces + other fixes [skip ci]

* error handling

* [skip ci] [wip] check if node supports mweb

* check fee before building tx

* [skip ci] minor

* [skip ci] minor

* mweb node setting [wip] [skip ci]

* prioritize mweb coins when selecting inputs from the pool

* potential connection edgecase fix

* translations + mweb node fixes

* don't use mweb for exchange refund address

* add peg in / out labels and make 6 confs only show up for peg in / out

* bump bitcoin_base version to v9

* [skip ci] fix logs page

* don't fetch txinfo for non-mweb addresses [skip ci]

* fix non-mweb confirmations

* rename always scan to enable mweb

* Update litecoin_wallet_addresses.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* Update cw_mweb.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* [skip ci] review updates pt.1

* [skip ci] minor code cleanup

* [skip ci] use exception handler

* exception handling [skip ci]

* [skip ci] exception handling

* trigger build

* pegout label fixes

* fix showing change transactions on peg-out

* minor code cleanup and minor peg-out fix

* final balance fixes

* non-mweb confirmations potential fix

* [skip ci] wip

* trigger build

---------

Co-authored-by: tuxpizza <tuxsudo@tux.pizza>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
Matthew Fosse
2024-11-07 04:57:36 +02:00
committed by GitHub
co-authored by Omar Hatem tuxpizza
parent 109d9b458e
commit c8cfc2cff1
55 changed files with 821 additions and 207 deletions
@@ -886,17 +886,37 @@ class BalanceRowWidget extends StatelessWidget {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${secondAvailableBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
height: 1,
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => launchUrl(
Uri.parse(
"https://guides.cakewallet.com/docs/cryptos/litecoin/#mweb"),
mode: LaunchMode.externalApplication,
),
child: Row(
children: [
Text(
'${secondAvailableBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor,
height: 1,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Icon(Icons.help_outline,
size: 16,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.labelTextColor),
)
],
),
),
SizedBox(height: 8),
@@ -0,0 +1,127 @@
import 'dart:io';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/utils/share_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
import 'package:cw_core/root_dir.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
class MwebLogsPage extends BasePage {
MwebLogsPage(this.mwebSettingsViewModelBase);
final MwebSettingsViewModelBase mwebSettingsViewModelBase;
@override
String get title => S.current.litecoin_mweb_logs;
@override
Widget body(BuildContext context) {
return Stack(
fit: StackFit.expand,
children: [
FutureBuilder<String>(
future: mwebSettingsViewModelBase.getAbbreviatedLogs(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text('No logs found'));
} else {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text(
snapshot.data!,
style: TextStyle(fontFamily: 'Monospace'),
),
),
);
}
},
),
Positioned(
child: LoadingPrimaryButton(
onPressed: () => onExportLogs(context),
text: S.of(context).export_logs,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
bottom: 24,
left: 24,
right: 24,
)
],
);
}
void onExportLogs(BuildContext context) {
if (Platform.isAndroid) {
onExportAndroid(context);
} else if (Platform.isIOS) {
share(context);
} else {
_saveFile();
}
}
void onExportAndroid(BuildContext context) {
showPopUp<void>(
context: context,
builder: (dialogContext) {
return AlertWithTwoActions(
alertTitle: S.of(context).export_backup,
alertContent: S.of(context).select_destination,
rightButtonText: S.of(context).save_to_downloads,
leftButtonText: S.of(context).share,
actionRightButton: () async {
const downloadDirPath = "/storage/emulated/0/Download";
final filePath = downloadDirPath + "/debug.log";
await mwebSettingsViewModelBase.saveLogsLocally(filePath);
Navigator.of(dialogContext).pop();
},
actionLeftButton: () async {
Navigator.of(dialogContext).pop();
try {
await share(context);
} catch (e, s) {
ExceptionHandler.onError(FlutterErrorDetails(
exception: e,
stack: s,
library: "Export Logs",
));
}
});
});
}
Future<void> share(BuildContext context) async {
final filePath = (await getAppDir()).path + "/debug.log";
bool success = await mwebSettingsViewModelBase.saveLogsLocally(filePath);
if (!success) return;
await ShareUtil.shareFile(filePath: filePath, fileName: "debug.log", context: context);
await mwebSettingsViewModelBase.removeLogsLocally(filePath);
}
Future<void> _saveFile() async {
String? outputFile = await FilePicker.platform
.saveFile(dialogTitle: 'Save Your File to desired location', fileName: "debug.log");
try {
final filePath = (await getApplicationSupportDirectory()).path + "/debug.log";
File debugLogFile = File(filePath);
await debugLogFile.copy(outputFile!);
} catch (exception, stackTrace) {
ExceptionHandler.onError(FlutterErrorDetails(
exception: exception,
stack: stackTrace,
library: "Export Logs",
));
}
}
}
@@ -0,0 +1,56 @@
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class MwebNodePage extends BasePage {
MwebNodePage(this.mwebSettingsViewModelBase)
: _nodeUriController = TextEditingController(text: mwebSettingsViewModelBase.mwebNodeUri),
super();
final MwebSettingsViewModelBase mwebSettingsViewModelBase;
final TextEditingController _nodeUriController;
@override
String get title => S.current.litecoin_mweb_node;
@override
Widget body(BuildContext context) {
return Stack(
fit: StackFit.expand,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(controller: _nodeUriController),
)
],
),
),
Positioned(
child: Observer(
builder: (_) => LoadingPrimaryButton(
onPressed: () => save(context),
text: S.of(context).save,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
bottom: 24,
left: 24,
right: 24,
)
],
);
}
void save(BuildContext context) {
mwebSettingsViewModelBase.setMwebNodeUri(_nodeUriController.text);
Navigator.pop(context);
}
}
+9 -1
View File
@@ -31,7 +31,7 @@ class MwebSettingsPage extends BasePage {
},
),
SettingsSwitcherCell(
title: S.current.litecoin_mweb_always_scan,
title: S.current.litecoin_mweb_enable,
value: _mwebSettingsViewModel.mwebEnabled,
onValueChange: (_, bool value) {
_mwebSettingsViewModel.setMwebEnabled(value);
@@ -41,6 +41,14 @@ class MwebSettingsPage extends BasePage {
title: S.current.litecoin_mweb_scanning,
handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.rescan),
),
SettingsCellWithArrow(
title: S.current.litecoin_mweb_logs,
handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.mwebLogs),
),
SettingsCellWithArrow(
title: S.current.litecoin_mweb_node,
handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.mwebNode),
),
],
),
);