Skip to content

Commit 468f5ea

Browse files
Adds optional email-body content and diagnostics fields
1 parent bc772fc commit 468f5ea

19 files changed

Lines changed: 915 additions & 149 deletions

.github/workflows/ci.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
test:
12+
name: Flutter ${{ matrix.sdk }}
13+
runs-on: ubuntu-latest
14+
timeout-minutes: 20
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
sdk:
19+
- '3.27.0'
20+
- stable
21+
22+
steps:
23+
- name: Check out repository
24+
uses: actions/checkout@v6
25+
26+
- name: Set up Flutter 3.27.0
27+
if: matrix.sdk == '3.27.0'
28+
uses: subosito/flutter-action@v2
29+
with:
30+
channel: stable
31+
flutter-version: '3.27.0'
32+
cache: true
33+
34+
- name: Set up current Flutter stable
35+
if: matrix.sdk == 'stable'
36+
uses: subosito/flutter-action@v2
37+
with:
38+
channel: stable
39+
cache: true
40+
41+
- name: Install package dependencies
42+
run: flutter pub get
43+
44+
- name: Check formatting
45+
run: dart format --output=none --set-exit-if-changed lib test example/lib example/test
46+
47+
- name: Analyze package
48+
run: flutter analyze
49+
50+
- name: Test package
51+
run: flutter test
52+
53+
- name: Install example dependencies
54+
working-directory: example
55+
run: flutter pub get
56+
57+
- name: Test example
58+
working-directory: example
59+
run: flutter test

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
## 0.3.0
2+
3+
* Add an optional pre-filled email body.
4+
* Add runtime diagnostics for the app and operating system.
5+
* Allow applications to append their own diagnostic fields.
6+
* Return the platform launch result from `sendEmail`.
7+
* Bound asynchronous diagnostic collection so email launches are still
8+
attempted when metadata lookup stalls.
9+
* Add `package_info_plus` 8.3.1 through 8.x. This dependency is registered for
10+
every consuming app, even when runtime diagnostics are disabled. This is an
11+
integration-breaking change for applications below Android API 19, iOS 12,
12+
or macOS 10.14, or applications using older Android build tooling. Version
13+
8.x is pinned to prevent newer major versions from silently raising those
14+
requirements. See the README for the complete native requirements.
15+
* Disable the feedback button while an email launch is in progress to prevent
16+
repeated taps from opening multiple composers.
17+
118
## 0.2.0
219

320
* Expose `sendEmail` utility function for custom button implementations

README.md

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,81 @@
11
# SendEmailFeedbackButton
22

3-
A simple Flutter button widget that opens the user's default email client with a pre-filled recipient and subject for sending feedback.
3+
A reusable Flutter button and utility API that opens the user's default email
4+
client with a pre-filled feedback message.
45

56
![Demo](https://raw.githubusercontent.com/stephane-archer/flutter_send_email_feedback_button/main/assets/screenshots/demo.png)
67

78
## Features
89

9-
- Opens the default email app on tap.
10-
- Pre-fills recipient email address and subject line.
11-
- Uses `url_launcher` under the hood.
12-
- Lightweight and easy to use.
13-
- Exposes `sendEmail` utility function for custom button implementations.
10+
- Pre-fills the recipient, subject, and optional email body.
11+
- Optionally includes application and operating-system diagnostics.
12+
- Accepts application-specific diagnostic fields.
1413

15-
## Usage
14+
## Requirements
1615

17-
### Using the Widget
16+
- Dart 3.6 or later.
17+
- Flutter 3.27 or later.
18+
- This package uses `package_info_plus` 8.3.1 through 8.x.
19+
- Android builds require API 19 or later, compile SDK 34, Java 17, Android
20+
Gradle Plugin 8.3 or later, and Gradle 8.4 or later.
21+
- Apple builds require iOS 12 or later and macOS 10.14 or later.
1822

19-
``` Dart
23+
## Using the widget
24+
25+
```dart
2026
import 'package:flutter/material.dart';
2127
import 'package:send_email_feedback_button/send_email_feedback_button.dart';
2228
23-
class MyApp extends StatelessWidget {
29+
class FeedbackButton extends StatelessWidget {
30+
const FeedbackButton({super.key});
31+
2432
@override
2533
Widget build(BuildContext context) {
26-
return MaterialApp(
27-
home: Scaffold(
28-
body: Center(
29-
child: SendEmailFeedbackButton(
30-
emailAddress: "support@example.com",
31-
emailSubject: "App Feedback",
32-
),
33-
),
34-
),
34+
return const SendEmailFeedbackButton(
35+
emailAddress: 'support@example.com',
36+
emailSubject: 'App feedback',
37+
emailBody: 'Please describe the issue:',
38+
includeRuntimeDiagnostics: true,
39+
additionalDiagnostics: {
40+
'Most recent error': 'FileSystemException',
41+
'Publication mode': 'exclusive copy',
42+
},
43+
diagnosticsHeading: 'Diagnostics:',
3544
);
3645
}
3746
}
3847
```
3948

40-
### Using the Utility Function
49+
When runtime diagnostics are enabled, the package includes the application
50+
name, package identifier, version/build number, operating-system name, and OS
51+
version. Values passed through `additionalDiagnostics` are controlled entirely
52+
by the calling application.
4153

42-
For custom button implementations, you can use the `sendEmail` function directly:
54+
If runtime metadata cannot be collected, the email launch is still attempted
55+
and the message reports that runtime diagnostics were unavailable.
4356

44-
``` Dart
45-
import 'package:flutter/material.dart';
46-
import 'package:send_email_feedback_button/send_email_feedback_button.dart';
57+
Collecting runtime metadata can delay the launch by up to two seconds. The
58+
widget is disabled while a launch is in progress so repeated taps do not open
59+
multiple email composers. On web, a diagnostics-enabled launch uses the current
60+
browsing context because browsers may block a new window after an asynchronous
61+
metadata lookup.
4762

48-
class MyApp extends StatelessWidget {
49-
@override
50-
Widget build(BuildContext context) {
51-
return MaterialApp(
52-
home: Scaffold(
53-
body: Center(
54-
child: OutlinedButton.icon(
55-
onPressed: () => sendEmail(
56-
emailAddress: "support@example.com",
57-
emailSubject: "App Feedback",
58-
),
59-
icon: Icon(Icons.email),
60-
label: Text("Send Feedback"),
61-
),
62-
),
63-
),
64-
);
65-
}
63+
## Using the utility function
64+
65+
For a custom button, call `sendEmail` directly:
66+
67+
```dart
68+
final launchRequested = await sendEmail(
69+
emailAddress: 'support@example.com',
70+
emailSubject: 'App feedback',
71+
emailBody: 'Please describe the issue:',
72+
includeRuntimeDiagnostics: true,
73+
additionalDiagnostics: {
74+
'Current screen': 'Export',
75+
},
76+
);
77+
78+
if (!launchRequested) {
79+
// Show an alternative contact method.
6680
}
67-
```
81+
```

example/android/app/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ android {
1111
ndkVersion = flutter.ndkVersion
1212

1313
compileOptions {
14-
sourceCompatibility = JavaVersion.VERSION_11
15-
targetCompatibility = JavaVersion.VERSION_11
14+
sourceCompatibility = JavaVersion.VERSION_17
15+
targetCompatibility = JavaVersion.VERSION_17
1616
}
1717

1818
kotlinOptions {
19-
jvmTarget = JavaVersion.VERSION_11.toString()
19+
jvmTarget = JavaVersion.VERSION_17.toString()
2020
}
2121

2222
defaultConfig {

example/lib/main.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ class MyHomePage extends StatelessWidget {
2828
return Scaffold(
2929
body: Center(
3030
child: SendEmailFeedbackButton(
31-
emailAddress: "support@example.com",
32-
emailSubject: "App Feedback & Test",
31+
emailAddress: 'support@example.com',
32+
emailSubject: 'App Feedback & Test',
33+
emailBody: 'Please describe the issue:',
34+
includeRuntimeDiagnostics: true,
35+
additionalDiagnostics: const {'Example mode': 'demo'},
3336
),
3437
),
3538
);

example/macos/Flutter/GeneratedPluginRegistrant.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import FlutterMacOS
66
import Foundation
77

8+
import package_info_plus
89
import url_launcher_macos
910

1011
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
12+
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
1113
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
1214
}

example/macos/Podfile.lock

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
PODS:
22
- FlutterMacOS (1.0.0)
3+
- package_info_plus (0.0.1):
4+
- FlutterMacOS
35
- url_launcher_macos (0.0.1):
46
- FlutterMacOS
57

68
DEPENDENCIES:
79
- FlutterMacOS (from `Flutter/ephemeral`)
10+
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
811
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
912

1013
EXTERNAL SOURCES:
1114
FlutterMacOS:
1215
:path: Flutter/ephemeral
16+
package_info_plus:
17+
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
1318
url_launcher_macos:
1419
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
1520

1621
SPEC CHECKSUMS:
1722
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
18-
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
23+
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
24+
url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd
1925

2026
PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009
2127

0 commit comments

Comments
 (0)