diff --git a/CHANGELOG.md b/CHANGELOG.md index 099d809d3..584859efa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Setting to use colorized usernames - contribution from @ggichure. - Show the number of new comments a read post has received since last visited - Added ability to mark read on scroll - contribution from @Fmstrat +- Added Error and crash reporting using a logs.txt- contribution from @ggichure - Added barebones support for video players. Youtube and video codecs - contribution from @ggichure. ## Changed diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d9e9f79bd..cdcbeeac7 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -539,6 +539,12 @@ "@countUsersActiveWeek": { "description": "Number of users active in the last week" }, + "crashReports": "Crash Reports", + "@crashReports": { + "description": "Initiates the process of sending a crash report to developers." + }, + "crashReportsView": "View Crash Reports", + "@crashReportsView": {}, "createAccount": "Create Account", "@createAccount": {}, "createComment": "Create Comment", @@ -1801,6 +1807,10 @@ "@report": {}, "reportComment": "Report Comment", "@reportComment": {}, + "reportCrashLogsTooltip": "Inspect Crash Reports Before Sending to Developers", + "@reportCrashLogsTooltip": { + "description": "Provides the ability to review crash reports and their details before sending them to developers for analysis." + }, "reporter": "Reporter:", "@reporter": { "description": "Name of reporter that reported a post/comment" diff --git a/lib/main.dart b/lib/main.dart index 511c977ec..38b67ac0b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'dart:io'; // Flutter imports +import 'package:catcher_2/catcher_2.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -70,7 +71,10 @@ Future initializeDatabase() async { void main() async { WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); - +// catcher + String filePath = join((await getApplicationDocumentsDirectory()).path, 'thunder_log.txt'); + Catcher2Options debugOptions = Catcher2Options(SilentReportMode(), [FileHandler(File(filePath), printLogs: true)]); + Catcher2Options releaseOptions = Catcher2Options(SilentReportMode(), [FileHandler(File(filePath))]); // Setting SystemUIMode SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); @@ -90,7 +94,7 @@ void main() async { // Perform preference migrations await performSharedPreferencesMigration(); - runApp(const ThunderApp()); + Catcher2(rootWidget: const ThunderApp(), debugConfig: debugOptions, releaseConfig: releaseOptions); if (!kIsWeb && Platform.isAndroid) { // Set high refresh rate after app initialization diff --git a/lib/routes.dart b/lib/routes.dart index 882c41c8b..39039a3fa 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,3 +1,4 @@ +import 'package:catcher_2/catcher_2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -27,6 +28,7 @@ import 'package:thunder/user/pages/user_settings_page.dart'; PageController thunderPageController = PageController(initialPage: 0); final GoRouter router = GoRouter( + navigatorKey: Catcher2.navigatorKey, debugLogDiagnostics: true, routes: [ GoRoute( diff --git a/lib/settings/pages/debug_settings_page.dart b/lib/settings/pages/debug_settings_page.dart index ef040eaef..e73f31129 100644 --- a/lib/settings/pages/debug_settings_page.dart +++ b/lib/settings/pages/debug_settings_page.dart @@ -292,6 +292,50 @@ class _DebugSettingsPageState extends State { }, ), ), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(l10n.crashReports, style: theme.textTheme.titleMedium), + const SizedBox(height: 8.0), + ], + ), + ), + ), + const SliverToBoxAdapter(child: SizedBox(height: 8.0)), + SliverToBoxAdapter( + child: SettingsListTile( + icon: Icons.bug_report, + subtitle: l10n.reportCrashLogsTooltip, + description: l10n.crashReportsView, + widget: Container(), + onTap: () async { + String filePath = join((await getApplicationDocumentsDirectory()).path, 'thunder_log.txt'); + final file = File(filePath); + + final contents = await file.readAsString(); + + if (context.mounted) { + await showThunderDialog( + context: context, + title: l10n.crashReports, + contentWidgetBuilder: (setPrimaryButtonEnabled) => SingleChildScrollView(child: Text(contents)), + primaryButtonText: l10n.copy, + primaryButtonInitialEnabled: true, + onPrimaryButtonPressed: (dialogContext, setPrimaryButtonEnabled) async { + await Clipboard.setData(ClipboardData(text: contents)); + if (context.mounted) dialogContext.pop(); + }, + secondaryButtonText: l10n.cancel, + onSecondaryButtonPressed: (dialogContext) => dialogContext.pop(), + ); + } + }, + ), + ), + const SliverToBoxAdapter(child: SizedBox(height: 8.0)), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 8.0), diff --git a/pubspec.lock b/pubspec.lock index 20b341c4f..242a07bd5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -209,6 +209,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + catcher_2: + dependency: "direct main" + description: + name: catcher_2 + sha256: "2c2c6f8cf8c817730cd1dbb010d55292396930e7a3d42c04c3039e3fd411a2f8" + url: "https://pub.dev" + source: hosted + version: "1.2.6" characters: dependency: transitive description: @@ -748,6 +756,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_mailer: + dependency: transitive + description: + name: flutter_mailer + sha256: "4fffaa35e911ff5ec2e5a4ebbca62c372e99a154eb3bb2c0bf79f09adf6ecf4c" + url: "https://pub.dev" + source: hosted + version: "2.1.2" flutter_markdown: dependency: "direct main" description: @@ -806,6 +822,14 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: transitive + description: + name: fluttertoast + sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66" + url: "https://pub.dev" + source: hosted + version: "8.2.5" freezed_annotation: dependency: transitive description: @@ -1096,6 +1120,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + mailer: + dependency: transitive + description: + name: mailer + sha256: d25d89555c1031abacb448f07b801d7c01b4c21d4558e944b12b64394c84a3cb + url: "https://pub.dev" + source: hosted + version: "6.1.0" markdown: dependency: transitive description: @@ -1478,6 +1510,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + sentry: + dependency: transitive + description: + name: sentry + sha256: fd1fbfe860c05f5c52820ec4dbf2b6473789e83ead26cfc18bca4fe80bf3f008 + url: "https://pub.dev" + source: hosted + version: "8.2.0" share_plus: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index ee2b5810c..9bac9f435 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -109,9 +109,9 @@ dependencies: sqlite3_flutter_libs: ^0.5.20 connectivity_plus: ^6.0.2 super_sliver_list: ^0.4.1 + catcher_2: ^1.2.6 video_player: ^2.8.7 - dev_dependencies: build_runner: ^2.4.6 flutter_test: