tracebird_flutter 0.1.0 copy "tracebird_flutter: ^0.1.0" to clipboard
tracebird_flutter: ^0.1.0 copied to clipboard

Tester feedback for Flutter apps: shake to report, annotate the screen, and every report ships with logs, failed requests and device context.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:tracebird_flutter/tracebird_flutter.dart';
import 'package:webview_flutter/webview_flutter.dart';

/// A deliberately broken checkout, so there is something worth reporting.
Future<void> main() async {
  await Tracebird.init(
    const TracebirdOptions(
      projectKey: String.fromEnvironment('TRACEBIRD_KEY', defaultValue: 'pk_live_site_dev'),
      endpoint: String.fromEnvironment(
        'TRACEBIRD_ENDPOINT',
        defaultValue: 'https://api.tracebird.dev',
      ),
      environment: 'staging',
      release: '1.4.2',
      tester: 'Sam K.',
      trigger: TracebirdTrigger.floatingButton,
      verbose: true,
    ),
  );
  runApp(const TracebirdWrapper(child: ExampleApp()));
}

/// The example application.
class ExampleApp extends StatelessWidget {
  /// Creates the example app.
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tracebird example',
      debugShowCheckedModeBanner: false,
      navigatorObservers: <NavigatorObserver>[TracebirdNavigatorObserver()],
      theme: ThemeData.dark(useMaterial3: true).copyWith(
        scaffoldBackgroundColor: const Color(0xFF0B0D11),
      ),
      routes: <String, WidgetBuilder>{
        '/': (_) => const CheckoutScreen(),
      },
    );
  }
}

/// A checkout screen whose pay button fails on purpose.
class CheckoutScreen extends StatefulWidget {
  /// Creates the checkout screen.
  const CheckoutScreen({super.key});

  @override
  State<CheckoutScreen> createState() => _CheckoutScreenState();
}

const String _promoHtml = '<body style="margin:0;height:100%;display:grid;'
    'place-items:center;background:linear-gradient(120deg,#ff6b35,#f7c548 55%,'
    '#00d2ff);font:700 20px system-ui;color:#111">FREE DELIVERY (WEBVIEW)</body>';

class _CheckoutScreenState extends State<CheckoutScreen> {
  bool _paying = false;

  /// A platform view on the screen — the case that breaks naive capture on
  /// iOS, and the reason the SDK has a native fallback at all.
  late final WebViewController _promo = WebViewController()
    ..setJavaScriptMode(JavaScriptMode.unrestricted)
    ..loadHtmlString(_promoHtml);

  /// Fails the way a real payment fails: a 500, then a null dereference.
  Future<void> _pay() async {
    setState(() => _paying = true);
    Tracebird.log('[checkout] submitting payment…');
    await Future<void>.delayed(const Duration(milliseconds: 600));

    Tracebird.recordHttp(
      method: 'POST',
      url: 'https://api.example.com/api/payments',
      status: 500,
      milliseconds: 612,
    );
    Tracebird.log(
      '[checkout] payment intent missing from response',
      level: LogLevel.error,
    );
    // The spinner deliberately never stops: that is the bug to report.
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Checkout'),
        backgroundColor: const Color(0xFF11141A),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            const Text('Order total', style: TextStyle(color: Color(0xFF8B93A1))),
            const SizedBox(height: 6),
            const Text(
              '€84.00',
              style: TextStyle(fontSize: 34, fontWeight: FontWeight.w700),
            ),
            const SizedBox(height: 14),
            SizedBox(
              height: 64,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(10),
                child: WebViewWidget(controller: _promo),
              ),
            ),
            const SizedBox(height: 14),
            // Wrapped so the tester cannot send you someone's card details.
            TracebirdMask(
              child: Card(
                color: const Color(0xFF11141A),
                child: ListTile(
                  leading: const Icon(Icons.credit_card),
                  title: const Text('4242 4242 4242 4242'),
                  subtitle: const Text('Sam K. · 04/29'),
                ),
              ),
            ),
            const SizedBox(height: 8),
            const Text(
              'The card is wrapped in TracebirdMask; the banner above it is a '
              'WebView, which only a native capture can see on iOS.',
              style: TextStyle(color: Color(0xFF8B93A1), fontSize: 11),
            ),
            const Spacer(),
            FilledButton(
              onPressed: _paying ? null : _pay,
              style: FilledButton.styleFrom(
                backgroundColor: const Color(0xFF8B5CF6),
                minimumSize: const Size.fromHeight(50),
              ),
              child: _paying
                  ? const SizedBox(
                      width: 20,
                      height: 20,
                      child: CircularProgressIndicator(
                        strokeWidth: 2,
                        color: Colors.white,
                      ),
                    )
                  : const Text('Pay €84.00'),
            ),
            const SizedBox(height: 12),
            const Text(
              'Tap Pay, watch it hang, then tap the violet button to report it.',
              textAlign: TextAlign.center,
              style: TextStyle(color: Color(0xFF8B93A1), fontSize: 12),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
150
points
0
downloads

Documentation

Documentation
API reference

Publisher

verified publishertracebird.dev

Weekly Downloads

Tester feedback for Flutter apps: shake to report, annotate the screen, and every report ships with logs, failed requests and device context.

Homepage
Repository (GitHub)
View/report issues

Topics

#feedback #bug-reporting #testing #qa

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on tracebird_flutter

Packages that implement tracebird_flutter