|
|
|
class LoggingElevatedButton extends ElevatedButton implements ActionLogger { |
|
LoggingElevatedButton({ |
|
required this.name, |
|
this.parameters, |
|
this.onError, |
|
AsyncCallback? onPressed, |
|
required super.child, |
|
super.style, |
|
}) : super( |
|
onPressed: ActionLogger.wrap( |
|
'btn', |
|
name, |
|
parameters, |
|
onPressed, |
|
onError, |
|
), |
|
); |
|
|
|
@override |
|
final String name; |
|
|
|
@override |
|
final Map<String, Object?>? parameters; |
|
|
|
@override |
|
final void Function(Object error)? onError; |
|
} |
|
|
|
abstract class ActionLogger { |
|
String get name; |
|
|
|
Map<String, Object?>? get parameters; |
|
|
|
void Function(Object error)? get onError; |
|
|
|
static VoidCallback? wrap( |
|
String? prefix, |
|
String name, |
|
Map<String, Object?>? parameters, |
|
AsyncCallback? action, |
|
void Function(Object)? onError, |
|
) { |
|
if (action == null) { |
|
return null; |
|
} |
|
return () async { |
|
try { |
|
// This could be customized by making it a static method that you set in |
|
// your app's main function. |
|
unawaited(FirebaseAnalytics.instance.logEvent( |
|
name: prefix == null ? name : '${prefix}_$name', |
|
parameters: parameters, |
|
)); |
|
await action(); |
|
} catch (error) { |
|
onError?.call(error); |
|
rethrow; |
|
} |
|
}; |
|
} |
|
|
|
// Use this method for `onError` if you'd like to display an error message to |
|
// the user. |
|
static void Function(Object) toastOnError( |
|
BuildContext context, { |
|
MessageBuilder? messageBuilder, |
|
}) { |
|
return (Object error) async { |
|
if (!context.mounted) { |
|
// Welp nothing we can really do here. |
|
return; |
|
} |
|
final ScaffoldMessengerState messenger = ScaffoldMessenger.of(context); |
|
messenger.showSnackBar( |
|
SnackBar( |
|
duration: const Duration(seconds: 2), |
|
content: Row( |
|
children: [ |
|
Expanded( |
|
child: |
|
messageBuilder?.call(error) ?? const Text('Action failed.'), |
|
), |
|
TextButton( |
|
child: Text( |
|
'give feedback', |
|
style: TextStyle( |
|
color: Theme.of(context).colorScheme.secondary, |
|
), |
|
), |
|
onPressed: () { |
|
messenger.clearSnackBars(); |
|
DribbleBloc.instance.modal.value = const FeedbackModal(); |
|
}, |
|
), |
|
], |
|
), |
|
), |
|
); |
|
}; |
|
} |
|
} |