outcode_bug_reporter 2.1.1 copy "outcode_bug_reporter: ^2.1.1" to clipboard
outcode_bug_reporter: ^2.1.1 copied to clipboard

In-app bug reporter for Flutter: a floating button that captures the screen, lets users annotate and redact it, set a severity, and file it to ClickUp or any backend.

outcode_bug_reporter #

2.1.1 #

Fixed #

  • The reporter now works in release builds at all. Capture read RenderRepaintBoundary.debugNeedsPaint, which assigns its result inside an assert. Asserts are stripped from release builds, so reading it threw LateInitializationError, and because the read sat outside the surrounding try the error escaped captureBoundary(), propagated out of open(), and was swallowed by its .ignore(). In any release or profile build, tapping the floating button hid it and nothing else ever happened — no error, and no way to open the reporter again for the rest of the session. Debug builds were unaffected, which is why it went unnoticed: flutter test runs with asserts enabled, so no widget test can reproduce it. The check is now guarded by kDebugMode, the whole capture body sits inside the try, and open() reports a thrown capture through FlutterError.reportError and resets its state so it can never latch again. If you are on 2.1.0, upgrade — the reporter does not function in your shipped builds.
  • The floating button no longer lags behind your finger. Dragging accumulated each onPanUpdate delta onto a field that is only written during build(), but Flutter flushes every queued pointer event in one synchronous pass with no build in between — so all but the last event in a frame read the same stale base and threw their delta away. On a high-refresh digitizer that meant the button travelled a fraction of the distance the finger did, falling further behind for the whole gesture. Position is now driven from details.globalPosition minus the grab offset, which is idempotent per event. dragStartBehavior: DragStartBehavior.down also recovers the first 36 logical pixels (kPanSlop) that the tap/pan arena previously discarded, so the drag starts where your finger does. Re-grabbing mid snap-back no longer jumps, and the button is wrapped in a RepaintBoundary so its shadow and halo stop re-rasterizing the app behind it.
  • The report form no longer claims "Screenshot attached" when the capture produced nothing; it says so instead, and hides the edit affordance that led to an empty editor.

Added #

  • BugReporterConfig.fabColor — colours the floating button and its halo only, leaving the rest of the flow on the theme accent. The button's icon colour is derived from it, so a light brand colour gets a dark glyph instead of white-on-white.
  • BugReporterTheme.withAccent(Color) — a copy with the accent applied and accentPress, ring and onAccent derived from it. Prefer it over copyWith(accent: ...), which leaves those three on the preset's values and so leaves an indigo halo behind a custom accent. Mirrors deriveAccentTokens() in the JS core.
  • Device brand and model rows. Supply deviceInfo['brand'] / ['manufacturer'] / ['model'] (e.g. from device_info_plus) and reports gain Brand name and Model rows. Brands are title-cased and fall back to the manufacturer when a carrier has rewritten them; the model string is kept verbatim. The package still takes no plugin dependencies — normalizeDeviceIdentity() mirrors the JS core's helper and only cleans up what you inject.

Changed #

  • Context row labels are 78px wide (was 74px), matching the web and React Native forms so a label like "Brand name" is not clipped.

2.1.0 #

Added #

  • Shake to report. BugReporterConfig.shake takes a ShakeOptions with an accelerometer callback; shaking the device opens the reporter. It stays off until you provide the stream, because the package still takes no plugin dependencies — one expression with sensors_plus, or any sample source you already have. ShakeDetector is exported on its own: pure Dart, no timers, no subscriptions, and driven by an injectable clock so it is unit-tested against a fake one.
  • BugReporterConfig.showButton (default true) — set false for a shake-only or controller-only build, with no visible bug button.

The detector shares its defaults with @outcode/bug-reporter-native (packages/core/src/shake.ts), so the gesture feels identical on both. It needs about a second of sustained shaking past 1.2g and then goes quiet for three seconds, so a phone set down hard doesn't file a bug. The reporter stops listening while a report is open and while the app is backgrounded, and mutes when the flow closes so the shake that dismissed it can't reopen it.

Security #

  • Redaction now fails closed. The annotate step flattens annotations into the screenshot before submitting. If that flatten failed, the editor fell back to the original capture — so a report where the user had redacted a password or a customer name could file that content unredacted, silently and with the normal success flow. When flattening fails and at least one redaction block was drawn, the submit is now aborted, the editor stays open, and an error explains that nothing was sent; Continue retries. Reports with no redaction still fall back to the unflattened capture, which is safe — there was nothing hidden to lose.

Fixed #

Fixes for the two pub.flutter-io.cn score deductions on 2.0.0 (140/160). Both needed a published version to take effect, so they ship here.

  • Shortened the package description to 166 characters; pub.flutter-io.cn requires 60–180 and 2.0.0 shipped 205.
  • Added example/ back inside the package so pub.flutter-io.cn's Example tab is populated — a minimal MaterialApp.builder integration, with the full demo staying at example-flutter/ in the repo root.

The third deduction is not in the package: pub.flutter-io.cn reports the homepage, repository, and issue_tracker URLs as unreachable because github.com/OutCode-Software/bug-reporter returns 404. Publishing the repository fixes that on pub.flutter-io.cn's next analysis, with no release needed.

2.0.0 #

First release of the Flutter package.

Ported from @outcode/bug-reporter-core + @outcode/bug-reporter-native, and versioned 2.0.0 to join the rest of the family at the same number — a 2.0.0 report looks the same whether it was filed from Flutter, the web, or React Native.

Added #

  • BugReporter — one widget, mounted in MaterialApp.builder, running the full idle → capture → annotate → form → submitting → done flow, plus BugReporterController for opening it from your own code and enabled for compiling it out of release builds.
  • Screenshot capture via Flutter's own RepaintBoundary — no plugin, and no platform channel, so Android, iOS, web, macOS, Windows, and Linux all work out of the box. ScreenshotOptions.maxWidth is applied as a capture pixel ratio.
  • Annotation editor with pen, arrow, box, opaque redaction, and text labels; 8-colour palette; undo and clear. Annotations are flattened at the resolution of the original capture, and survive a round-trip through the form's "Edit" button.
  • The flow is presented as a route (ReportFlowRoute) pushed on top of whatever is on screen, so it lands above an open dialog or bottom sheet, text selection and tooltips get the Overlay they need, and the system back gesture steps back through the reporter (PopScope) instead of popping the app's own screen out from under it. Mounted in MaterialApp.builder the widget sits above the Navigator, so it locates it by descending from its own element rather than via Navigator.of(context) (which searches ancestors); pass navigatorKey to skip the search. With no navigator at all, the flow falls back to an Overlay the reporter owns.

Verified on device #

Built and driven end-to-end on a Samsung SCG07 (Android 13): capture excludes the button, arrow and opaque redaction render and flatten, the form reports 12 context rows including Route, the keyboard leaves Submit reachable, submit attaches a ~149 KB PNG, and back closes the reporter while leaving the app's own dialog open.

  • Auto-captured context: route (with BugReporterNavigatorObserver), platform, release, device, viewport, screen, text scale, orientation, colour scheme, locale, timezone, and console/network summaries.
  • BugReporterTheme with the shared Indigo / Noir / Mint presets and copyWith token overrides.
  • ClickUpBugReporterRepository, byte-comparable report bodies with the JS core: markdown context block, Recent Logs, Last Failed API Call, screenshot attachment, and best-effort tag attachment after task creation.
  • Default HTTP backend via apiUrl, using the same snake_case payload as the JS packages.
  • ReportQueue + ReportQueueStorage offline retry queue (10-entry cap, drops screenshots rather than reports when storage is full), with InMemoryReportQueueStorage for tests and demos.
  • BugReporterLogCapture for breadcrumbs from FlutterError.onError, PlatformDispatcher.onError, and debugPrint — chaining to existing handlers so it composes with Crashlytics/Sentry — plus BugReporterHttpClient to record failed requests.
0
likes
160
points
147
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

In-app bug reporter for Flutter: a floating button that captures the screen, lets users annotate and redact it, set a severity, and file it to ClickUp or any backend.

Homepage
Repository (GitHub)
View/report issues

Topics

#bug-report #feedback #screenshot #annotation #clickup

License

MIT (license)

Dependencies

flutter, http, http_parser

More

Packages that depend on outcode_bug_reporter