Skip to content

Commit 1936c70

Browse files
authored
Merge branch 'main' into fix/jni-proguard-rules
2 parents 81e9bf5 + d21858c commit 1936c70

17 files changed

+1344
-246
lines changed

.github/workflows/metrics.yml

Lines changed: 69 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -22,75 +22,75 @@ jobs:
2222
with:
2323
access_token: ${{ github.token }}
2424

25-
# metrics:
26-
# name: ${{ matrix.name }}
27-
# runs-on: ${{ matrix.host }}
28-
# timeout-minutes: 30
29-
# strategy:
30-
# # We want that the matrix keeps running, default is to cancel all jobs if a single fails.
31-
# fail-fast: false
32-
# matrix:
33-
# include:
34-
# - platform: ios
35-
# name: iOS
36-
# appPlain: test-app-plain.ipa
37-
# host: macos-latest
38-
# - platform: android
39-
# name: Android
40-
# appPlain: metrics/perf-test-app-plain/build/app/outputs/apk/release/app-arm64-v8a-release.apk
41-
# host: ubuntu-latest
42-
#
43-
# steps:
44-
# - uses: actions/checkout@v4
45-
#
46-
# # Let's stick to an explicit version and update manually because a version change may affect results.
47-
# # If it would update implicitly it could confuse people to think the change is actually caused by the PR.
48-
# # Instead, we use Updater (update-deps.yml) to create PRs for explicit Flutter SDK update.
49-
# - name: Read configured Flutter SDK version
50-
# id: conf
51-
# run: |
52-
# version=$(grep "version" metrics/flutter.properties | cut -d'=' -f2 | xargs)
53-
# echo "flutter=$version" >> "$GITHUB_OUTPUT"
54-
#
55-
# - name: Install Flutter v${{ steps.conf.outputs.flutter }}
56-
# uses: subosito/flutter-action@395322a6cded4e9ed503aebd4cc1965625f8e59a # [email protected]
57-
# with:
58-
# flutter-version: ${{ steps.conf.outputs.flutter }}
59-
#
60-
# - uses: actions/setup-java@v4
61-
# if: ${{ matrix.platform == 'android' }}
62-
# with:
63-
# java-version: "17"
64-
# distribution: "adopt"
65-
#
66-
# - run: ./metrics/prepare.sh
67-
#
68-
# - uses: actions/cache@v4
69-
# id: app-plain-cache
70-
# with:
71-
# path: ${{ matrix.appPlain }}
72-
# key: ${{ github.workflow }}-${{ github.job }}-appplain-${{ matrix.platform }}-${{ hashFiles('metrics/perf-test-app-plain/pubspec.yaml') }}
73-
#
74-
# - name: Build
75-
# run: ./metrics/build.sh ${{ matrix.platform }}
76-
# env:
77-
# # Necessary to build an iOS .ipa (using fastlane)
78-
# APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
79-
# APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
80-
# APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }}
81-
# FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }}
82-
# MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }}
83-
# MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
84-
# MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }}
85-
# APP_PLAIN: ${{ matrix.appPlain }}
86-
#
87-
# - name: Collect apps metrics
88-
# uses: getsentry/action-app-sdk-overhead-metrics@v1
89-
# with:
90-
# name: ${{ matrix.name }}
91-
# config: ./metrics/metrics-${{ matrix.platform }}.yml
92-
# sauce-user: ${{ secrets.SAUCE_USERNAME }}
93-
# sauce-key: ${{ secrets.SAUCE_ACCESS_KEY }}
25+
metrics:
26+
name: ${{ matrix.name }}
27+
runs-on: ${{ matrix.host }}
28+
timeout-minutes: 30
29+
strategy:
30+
# We want that the matrix keeps running, default is to cancel all jobs if a single fails.
31+
fail-fast: false
32+
matrix:
33+
include:
34+
- platform: ios
35+
name: iOS
36+
appPlain: test-app-plain.ipa
37+
host: macos-latest
38+
- platform: android
39+
name: Android
40+
appPlain: metrics/perf-test-app-plain/build/app/outputs/apk/release/app-arm64-v8a-release.apk
41+
host: ubuntu-latest
42+
43+
steps:
44+
- uses: actions/checkout@v4
45+
46+
# Let's stick to an explicit version and update manually because a version change may affect results.
47+
# If it would update implicitly it could confuse people to think the change is actually caused by the PR.
48+
# Instead, we use Updater (update-deps.yml) to create PRs for explicit Flutter SDK update.
49+
- name: Read configured Flutter SDK version
50+
id: conf
51+
run: |
52+
version=$(grep "version" metrics/flutter.properties | cut -d'=' -f2 | xargs)
53+
echo "flutter=$version" >> "$GITHUB_OUTPUT"
54+
55+
- name: Install Flutter v${{ steps.conf.outputs.flutter }}
56+
uses: subosito/flutter-action@395322a6cded4e9ed503aebd4cc1965625f8e59a # [email protected]
57+
with:
58+
flutter-version: ${{ steps.conf.outputs.flutter }}
59+
60+
- uses: actions/setup-java@v4
61+
if: ${{ matrix.platform == 'android' }}
62+
with:
63+
java-version: "17"
64+
distribution: "adopt"
65+
66+
- run: ./metrics/prepare.sh
67+
68+
- uses: actions/cache@v4
69+
id: app-plain-cache
70+
with:
71+
path: ${{ matrix.appPlain }}
72+
key: ${{ github.workflow }}-${{ github.job }}-appplain-${{ matrix.platform }}-${{ hashFiles('metrics/perf-test-app-plain/pubspec.yaml') }}
73+
74+
- name: Build
75+
run: ./metrics/build.sh ${{ matrix.platform }}
76+
env:
77+
# Necessary to build an iOS .ipa (using fastlane)
78+
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
79+
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
80+
APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_KEY }}
81+
FASTLANE_KEYCHAIN_PASSWORD: ${{ secrets.FASTLANE_KEYCHAIN_PASSWORD }}
82+
MATCH_GIT_PRIVATE_KEY: ${{ secrets.MATCH_GIT_PRIVATE_KEY }}
83+
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
84+
MATCH_USERNAME: ${{ secrets.MATCH_USERNAME }}
85+
APP_PLAIN: ${{ matrix.appPlain }}
86+
87+
- name: Collect apps metrics
88+
uses: getsentry/action-app-sdk-overhead-metrics@v1
89+
with:
90+
name: ${{ matrix.name }}
91+
config: ./metrics/metrics-${{ matrix.platform }}.yml
92+
sauce-user: ${{ secrets.SAUCE_USERNAME }}
93+
sauce-key: ${{ secrets.SAUCE_ACCESS_KEY }}
9494

9595
metrics-dart:
9696
name: Console

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Breaking Change (Tooling)
6+
7+
- Upgrade Kotlin `languageVersion` to `1.8` ([#3032](https://github.com/getsentry/sentry-dart/pull/3032))
8+
- This allows usage of the Kotlin Android Plugin `2.2.0` which requires a `languageVersion` of `1.8` or higher
9+
- If you are experiencing an issue we recommend upgrading to a toolchain compatible with Kotlin `1.8` or higher
10+
11+
### Features
12+
13+
- SentryFeedbackWidget Improvements ([#2964](https://github.com/getsentry/sentry-dart/pull/2964))
14+
- Capture a device screenshot for feedback
15+
- Customize tests and required fields
16+
- Customization moved from the `SentryFeedbackWidget` constructor to `SentryFlutterOptions`:
17+
```dart
18+
// configure your feedback widget
19+
options.feedback.showBranding = false;
20+
```
21+
322
## 9.2.0
423

524
### Features

dart/lib/src/sentry_attachment/sentry_attachment.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,12 @@ class SentryAttachment {
8989
);
9090

9191
SentryAttachment.fromScreenshotData(Uint8List bytes)
92-
: this.fromUint8List(bytes, 'screenshot.png',
93-
contentType: 'image/png',
94-
attachmentType: SentryAttachment.typeAttachmentDefault);
92+
: this.fromUint8List(
93+
bytes,
94+
'screenshot.png',
95+
contentType: 'image/png',
96+
attachmentType: SentryAttachment.typeAttachmentDefault,
97+
);
9598

9699
SentryAttachment.fromViewHierarchy(SentryViewHierarchy sentryViewHierarchy)
97100
: this.fromLoader(

dart/lib/src/type_check_hint.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:meta/meta.dart';
12
import 'http_client/failed_request_client.dart';
23

34
/// Constants used for Type Check hints.
@@ -19,4 +20,7 @@ class TypeCheckHint {
1920

2021
/// Used to indicate that the SDK added a synthetic current stack trace.
2122
static const currentStackTrace = 'currentStackTrace';
23+
24+
@internal
25+
static const isWidgetFeedback = 'isWidgetFeedback';
2226
}

flutter/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ android {
5555
}
5656
kotlinOptions {
5757
jvmTarget = JavaVersion.VERSION_1_8
58-
languageVersion = "1.6"
58+
languageVersion = "1.8"
5959
}
6060
}
6161

flutter/example/lib/main.dart

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -513,16 +513,10 @@ class MainScaffold extends StatelessWidget {
513513
TooltipButton(
514514
onPressed: () async {
515515
final id = await Sentry.captureMessage('UserFeedback');
516-
final screenshot = await SentryFlutter.captureScreenshot();
517-
518516
if (!context.mounted) return;
519-
Navigator.push(
517+
SentryFeedbackWidget.show(
520518
context,
521-
MaterialPageRoute(
522-
builder: (context) => SentryFeedbackWidget(
523-
associatedEventId: id, screenshot: screenshot),
524-
fullscreenDialog: true,
525-
),
519+
associatedEventId: id,
526520
);
527521
},
528522
text:

flutter/lib/src/event_processor/replay_event_processor.dart

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@ class ReplayEventProcessor implements EventProcessor {
1212

1313
@override
1414
Future<SentryEvent?> apply(SentryEvent event, Hint hint) async {
15-
final hasException = event.eventId != SentryId.empty() &&
15+
final isErrorEvent = event.eventId != SentryId.empty() &&
1616
event.exceptions?.isNotEmpty == true;
17-
final isFeedback =
17+
18+
final isFeedbackEvent =
1819
event.eventId != SentryId.empty() && event.type == 'feedback';
19-
final shouldCaptureReplay = hasException || isFeedback;
20+
final isWidgetFeedbackEvent =
21+
// ignore: invalid_use_of_internal_member
22+
hint.get(TypeCheckHint.isWidgetFeedback) == true;
23+
24+
final shouldCaptureReplay =
25+
isErrorEvent || (isFeedbackEvent && !isWidgetFeedbackEvent);
2026

2127
if (shouldCaptureReplay) {
2228
final isCrash =
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
class SentryFeedbackOptions {
2+
// Form Configuration
3+
4+
/// The title of the feedback form.
5+
var title = 'Report a Bug';
6+
7+
/// Requires the name field on the feedback form to be filled in.
8+
var isNameRequired = false;
9+
10+
/// Displays the name field on the feedback form. Ignored if `isNameRequired` is `true`.
11+
var showName = true;
12+
13+
/// Requires the email field on the feedback form to be filled in.
14+
var isEmailRequired = false;
15+
16+
/// Displays the email field on the feedback form. Ignored if `isEmailRequired` is `true`.
17+
var showEmail = true;
18+
19+
/// Sets the `email` and `name` fields to the corresponding Sentry SDK user fields that were called with `SentrySDK.setUser`.
20+
var useSentryUser = true;
21+
22+
/// Displays the Sentry logo inside the form
23+
var showBranding = true;
24+
25+
/// Displays the capture screenshot button on the feedback form
26+
var showCaptureScreenshot = true;
27+
28+
// Form Labels Configuration
29+
30+
/// The title of the feedback form.
31+
String formTitle = 'Report a Bug';
32+
33+
/// The label of the feedback description input field.
34+
String messageLabel = 'Description';
35+
36+
/// The placeholder in the feedback description input field.
37+
String messagePlaceholder = 'What\'s the bug? What did you expect?';
38+
39+
/// The text to attach to the title label for a required field.
40+
String isRequiredLabel = ' (Required)';
41+
42+
/// The message displayed after a successful feedback submission.
43+
String successMessageText = 'Thank you for your report!';
44+
45+
/// The label next to the name input field.
46+
String nameLabel = 'Name';
47+
48+
/// The placeholder in the name input field.
49+
String namePlaceholder = 'Your Name';
50+
51+
/// The label next to the email input field.
52+
String emailLabel = 'Email';
53+
54+
/// The placeholder in the email input field.
55+
String emailPlaceholder = '[email protected]';
56+
57+
/// The label of the submit button.
58+
String submitButtonLabel = 'Send Bug Report';
59+
60+
/// The label of the cancel button.
61+
String cancelButtonLabel = 'Cancel';
62+
63+
/// The label of the validation error message.
64+
String validationErrorLabel = 'Can\'t be empty';
65+
66+
/// The label of the capture screenshot button.
67+
String captureScreenshotButtonLabel = 'Capture a screenshot';
68+
69+
/// The label of the remove screenshot button.
70+
String removeScreenshotButtonLabel = 'Remove screenshot';
71+
72+
/// The label of the take screenshot button shown outside of the feedback widget.
73+
String takeScreenshotButtonLabel = 'Take Screenshot';
74+
}

0 commit comments

Comments
 (0)