arm_tooling 0.1.0
arm_tooling: ^0.1.0 copied to clipboard
Reusable client-side automated remote monitoring for Flutter web and mobile apps.
example/lib/main.dart
import 'package:arm_tooling/arm_tooling.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: 'replace-me',
appId: 'replace-me',
messagingSenderId: 'replace-me',
projectId: 'replace-me',
storageBucket: 'replace-me.firebasestorage.app',
),
);
final armClient = ArmClient(
sink: FirebaseArmSink(
firestore: FirebaseFirestore.instance,
storage: FirebaseStorage.instance,
),
appId: 'arm_tooling_example',
environment: kReleaseMode ? 'production' : 'debug',
routeProvider: () => '/example',
contextBuilder: () => <String, dynamic>{
'screen': 'example_home',
'platform': defaultTargetPlatform.name,
},
);
await ArmBootstrap.runGuarded(
client: armClient,
body: () async {
runApp(ExampleApp(armClient: armClient));
},
);
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key, required this.armClient});
final ArmClient armClient;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ARM Tooling Example',
home: ExampleHome(armClient: armClient),
);
}
}
class ExampleHome extends StatefulWidget {
const ExampleHome({super.key, required this.armClient});
final ArmClient armClient;
@override
State<ExampleHome> createState() => _ExampleHomeState();
}
class _ExampleHomeState extends State<ExampleHome> {
final _boundaryController = ArmCaptureBoundaryController();
String? _lastCaseId;
Future<void> _runSmokeTest() async {
try {
final result = await widget.armClient.captureException(
error: StateError('Manual example smoke test'),
stackTrace: StackTrace.current,
feature: 'example',
operation: 'manual_smoke_test',
severity: ArmSeverity.moderate,
category: 'smoke_test',
screenshotCapture: _boundaryController.capturePng,
recoverySnapshotBuilder: () => <String, dynamic>{
'requestedAt': DateTime.now().toUtc().toIso8601String(),
},
handled: true,
);
if (!mounted) return;
setState(() => _lastCaseId = result.caseId);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Logged ${result.caseId}')));
} catch (error) {
if (!mounted) return;
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Smoke test failed: $error')));
}
}
@override
Widget build(BuildContext context) {
return ArmCaptureBoundary(
controller: _boundaryController,
child: Scaffold(
appBar: AppBar(title: const Text('ARM Tooling Example')),
body: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 520),
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Use this page to verify that Firestore case logging and optional screenshot uploads are wired correctly.',
),
const SizedBox(height: 16),
FilledButton(
onPressed: _runSmokeTest,
child: const Text('Run ARM Smoke Test'),
),
if (_lastCaseId != null) ...[
const SizedBox(height: 16),
SelectableText('Last case ID: $_lastCaseId'),
],
],
),
),
),
),
),
);
}
}