diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 920f7ab..06b85eb 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -112,5 +112,12 @@
+
+
+
+
+
+
diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb
index 9393f36..a9d679d 100644
--- a/lib/l10n/app_de.arb
+++ b/lib/l10n/app_de.arb
@@ -45,6 +45,8 @@
"settings": "Einstellungen",
"about": "Über",
+ "reportBug": "Fehler melden",
+ "couldNotOpenLink": "Link konnte nicht geöffnet werden",
"appSettings": "App-Einstellungen",
"theme": "Design",
"themeLight": "Hell",
diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb
index a6a6e11..14355af 100644
--- a/lib/l10n/app_en.arb
+++ b/lib/l10n/app_en.arb
@@ -45,6 +45,8 @@
"settings": "Settings",
"about": "About",
+ "reportBug": "Report Bug",
+ "couldNotOpenLink": "Could not open link",
"appSettings": "App Settings",
"theme": "Theme",
"themeLight": "Light",
diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart
index 855eec9..c5020f5 100644
--- a/lib/l10n/app_localizations.dart
+++ b/lib/l10n/app_localizations.dart
@@ -356,6 +356,18 @@ abstract class AppLocalizations {
/// **'About'**
String get about;
+ /// No description provided for @reportBug.
+ ///
+ /// In en, this message translates to:
+ /// **'Report Bug'**
+ String get reportBug;
+
+ /// No description provided for @couldNotOpenLink.
+ ///
+ /// In en, this message translates to:
+ /// **'Could not open link'**
+ String get couldNotOpenLink;
+
/// No description provided for @appSettings.
///
/// In en, this message translates to:
diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart
index ed82870..7216340 100644
--- a/lib/l10n/app_localizations_de.dart
+++ b/lib/l10n/app_localizations_de.dart
@@ -137,6 +137,12 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get about => 'Über';
+ @override
+ String get reportBug => 'Fehler melden';
+
+ @override
+ String get couldNotOpenLink => 'Link konnte nicht geöffnet werden';
+
@override
String get appSettings => 'App-Einstellungen';
diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart
index efd3b48..3a6600c 100644
--- a/lib/l10n/app_localizations_en.dart
+++ b/lib/l10n/app_localizations_en.dart
@@ -137,6 +137,12 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get about => 'About';
+ @override
+ String get reportBug => 'Report Bug';
+
+ @override
+ String get couldNotOpenLink => 'Could not open link';
+
@override
String get appSettings => 'App Settings';
diff --git a/lib/widgets/app_menu_button.dart b/lib/widgets/app_menu_button.dart
index 3e95540..124786c 100644
--- a/lib/widgets/app_menu_button.dart
+++ b/lib/widgets/app_menu_button.dart
@@ -1,8 +1,11 @@
// Copyright (c) 2026 tmacinc
// Licensed under CC BY-NC-SA 4.0
+import 'dart:io';
+
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
+import 'package:url_launcher/url_launcher.dart';
import 'package:meshcore_team/screens/connection_screen.dart';
import 'package:meshcore_team/screens/settings_screen.dart';
import '../l10n/app_localizations.dart';
@@ -15,13 +18,41 @@ class AppMenuButton extends StatelessWidget {
Future _showAbout(BuildContext context) async {
final info = await PackageInfo.fromPlatform();
if (!context.mounted) return;
+ final l10n = AppLocalizations.of(context)!;
showAboutDialog(
context: context,
applicationName: 'MeshCore TEAM',
applicationVersion: 'v${info.version}',
+ children: [
+ TextButton.icon(
+ icon: const Icon(Icons.bug_report_outlined),
+ label: Text(l10n.reportBug),
+ onPressed: () => _reportBug(context, info),
+ ),
+ ],
);
}
+ Future _reportBug(BuildContext context, PackageInfo info) async {
+ final platform =
+ '${Platform.operatingSystem} ${Platform.operatingSystemVersion}';
+ final body = 'App version: ${info.version} (build ${info.buildNumber})\n'
+ 'Platform: $platform\n\n'
+ 'Describe the issue:\n';
+ final uri = Uri.https('github.com', '/tmacinc/MeshCore-TEAM/issues/new', {
+ 'body': body,
+ });
+
+ final l10n = AppLocalizations.of(context)!;
+ if (!await launchUrl(uri, mode: LaunchMode.externalApplication)) {
+ if (context.mounted) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text(l10n.couldNotOpenLink)),
+ );
+ }
+ }
+ }
+
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index be1ee9a..4f2ea53 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -18,6 +18,7 @@ import share_plus
import shared_preferences_foundation
import sqflite_darwin
import sqlite3_flutter_libs
+import url_launcher_macos
import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
@@ -34,5 +35,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
+ UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
}
diff --git a/pubspec.lock b/pubspec.lock
index 9f0aeb7..75cefa0 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -737,10 +737,10 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
+ sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
url: "https://pub.dev"
source: hosted
- version: "0.12.18"
+ version: "0.12.19"
material_color_utilities:
dependency: transitive
description:
@@ -753,10 +753,10 @@ packages:
dependency: transitive
description:
name: meta
- sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
+ sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
url: "https://pub.dev"
source: hosted
- version: "1.17.0"
+ version: "1.18.0"
mgrs_dart:
dependency: transitive
description:
@@ -1270,10 +1270,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
+ sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
url: "https://pub.dev"
source: hosted
- version: "0.7.9"
+ version: "0.7.11"
timezone:
dependency: transitive
description:
@@ -1314,6 +1314,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.0"
+ url_launcher:
+ dependency: "direct main"
+ description:
+ name: url_launcher
+ sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.3.2"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.3.32"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.4.1"
url_launcher_linux:
dependency: transitive
description:
@@ -1322,6 +1346,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.1"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.2.5"
url_launcher_platform_interface:
dependency: transitive
description:
@@ -1459,5 +1491,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
- dart: ">=3.9.0-0 <4.0.0"
- flutter: ">=3.27.0"
+ dart: ">=3.12.0 <4.0.0"
+ flutter: ">=3.44.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 1566550..83e438a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -64,6 +64,7 @@ dependencies:
# Utilities
crypto: ^3.0.3
+ url_launcher: ^6.3.2
http: ^1.2.0
package_info_plus: ^8.0.0
battery_plus: ^6.2.0