Compare commits

...

4 Commits

Author SHA1 Message Date
771938e545 Merge pull request 'dev' (#13) from github-such-software/hash-wallet:dev into dev
All checks were successful
Hash Wallet Linux build / build (push) Successful in 9m50s
Reviewed-on: #13
2026-05-17 20:36:07 -04:00
jwinterm
0b9c67f0e5 Drop flutter_mailer dependency from pubspec_base.yaml
All checks were successful
Hash Wallet Linux build / build (pull_request) Successful in 10m12s
The source-of-truth pubspec template — gitignored pubspec.yaml is
regenerated from this on each configure.dart run, so the dep would have
reappeared on next build. Follow-up to a8e071a05/4c09950e0.
2026-05-17 20:13:01 -04:00
jwinterm
4c09950e0b Replace broken flutter_mailer error-report send with GitHub issue launcher
flutter_mailer has no Linux implementation (throws MissingPluginException)
and on other platforms required users to have a configured mail client.
Vanishingly few error reports ever reached anyone. The 'Send' button on
the error popup was effectively a no-op.

Replaced with a url_launcher call that opens a prefilled GitHub issue at
github.com/Such-Software/hash-wallet/issues/new with the error trace
inlined into the body (truncated to ~6.5KB to stay under GitHub's URL
length cap; full log path is shown in the body for users who want to
attach it manually). Adds a 'bug,from-app' label and a short prompt
asking the user to describe what they were doing.

Downsides: people without a GitHub account will get nothing useful when
they hit 'Send' — they'll see GitHub's sign-up page. Net still better
than the silent no-op we had. Adding a real reporting endpoint
(Cloudflare Worker) is the obvious follow-up if low report volume
turns out to matter.

Also removed flutter_mailer from pubspec.yaml — was only used here.
2026-05-17 20:12:38 -04:00
jwinterm
3faa89d49d Wownero: route MoneroAccountListViewModel.selected to wownero API
The .selected computed getter always called monero!.getCurrentAccount(_wallet),
which does an internal 'wallet as MoneroWallet' cast and threw
'WowneroWallet is not a subtype of MoneroWallet' whenever the dashboard
CardsView Observer rebuilt for a Wownero wallet. The .accounts getter
above already dispatched correctly by wallet.type; .selected didn't.

Now matches the same monero/wownero dispatch pattern.
2026-05-17 20:03:07 -04:00
3 changed files with 45 additions and 26 deletions

View File

@@ -16,8 +16,8 @@ import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mailer/flutter_mailer.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
class ExceptionHandler {
static bool _hasError = false;
@@ -70,39 +70,60 @@ class ExceptionHandler {
);
}
// Hash Wallet: the original Cake implementation used flutter_mailer to
// hand the error.txt to the OS mail client. That plugin has no Linux
// implementation (throws MissingPluginException) and on other platforms
// many users have no mail client configured, so very few reports ever
// reached anyone. Instead, we open a prefilled GitHub issue. Users
// without a GH account get nothing useful, but the trade-off beats
// pretending the mail flow works.
//
// GitHub's "new issue" URL caps the body at ~8KB before truncating, so
// we send the tail of error.txt (most recent exception is usually most
// relevant) and prepend a hint to attach the full file.
static const _issueUrl =
'https://github.com/Such-Software/hash-wallet/issues/new';
static const _maxBodyChars = 6500;
static void _sendExceptionFile() async {
try {
if (_file == null) {
final appDocDir = await getAppDir();
_file = File('${appDocDir.path}/error.txt');
}
await _addDeviceInfo(_file!);
// Check if a mail client is available
final bool canSend = await FlutterMailer.canSendMail();
final fullBody = await _file!.readAsString();
final trimmed = fullBody.length > _maxBodyChars
? '...(truncated, full log at ${_file!.path})\n\n${fullBody.substring(fullBody.length - _maxBodyChars)}'
: fullBody;
if (Platform.isIOS && !canSend) {
printV('Mail app is not available');
final body = '''
<!-- Thanks for reporting. The trace below was captured automatically.
Please add a short description of what you were doing when the error
appeared (e.g. "creating wallet", "restoring from seed", "sending Tx"). -->
---
$trimmed
''';
final uri = Uri.https('github.com', '/Such-Software/hash-wallet/issues/new', {
'title': 'App error report',
'labels': 'bug,from-app',
'body': body,
});
final launched = await launchUrl(uri, mode: LaunchMode.externalApplication);
if (!launched) {
printV('Could not open GitHub issue URL: $uri');
return;
}
final MailOptions mailOptions = MailOptions(
subject: 'Mobile App Issue',
recipients: ['support@such.software'],
attachments: [_file!.path],
);
final result = await FlutterMailer.send(mailOptions);
// Clear file content if the error was sent or saved.
// On android we can't know if it was sent or saved
if (result.name == MailerResponse.sent.name ||
result.name == MailerResponse.saved.name ||
result.name == MailerResponse.android.name) {
_file!.writeAsString("", mode: FileMode.write);
}
// Clear the file now that the user has been handed the trace.
await _file!.writeAsString('', mode: FileMode.write);
} catch (e, s) {
_saveException(e.toString(), s);
}

View File

@@ -58,7 +58,9 @@ abstract class MoneroAccountListViewModelBase with Store {
@computed
AccountListItem get selected {
final currentId = monero!.getCurrentAccount(_wallet).id;
final currentId = _wallet.type == WalletType.wownero
? wownero!.getCurrentAccount(_wallet).id
: monero!.getCurrentAccount(_wallet).id;
return accounts.firstWhere((item) => item.id == currentId);
}

View File

@@ -75,10 +75,6 @@ dependencies:
url: https://github.com/MrCyjaneK/device_display_brightness.git
ref: 4cac18c446ce686f3d75b1565badbd7da439bbd9
wakelock_plus: ^1.2.5
flutter_mailer:
git:
url: https://github.com/taljacobson/flutter_mailer
ref: 9c4ed111a9151a2bbfb9afe2c18a37599c6f84f3
device_info_plus: ^9.1.0
base32: 2.1.3
in_app_review: ^2.0.6