61 lines
2.2 KiB
Dart
61 lines
2.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:image_picker/image_picker.dart';
|
|
|
|
/// Bottom sheet letting the user pick a photo from the camera or their
|
|
/// existing library. Shared by any screen that needs to snap or choose a
|
|
/// photo (receipt capture, VIN scanning) so the choice looks and behaves
|
|
/// the same everywhere. Pass [heading] to label what the photo is for
|
|
/// (e.g. receipt capture passes "Receipt From") — omitted by callers where
|
|
/// that's already obvious from context. [onInfoTap], if given, adds an
|
|
/// info button next to [heading] (e.g. VIN scanning uses it to explain
|
|
/// where to find a VIN); ignored if [heading] is null, since there'd be
|
|
/// nowhere to put it.
|
|
Future<ImageSource?> chooseImageSource(
|
|
BuildContext context, {
|
|
String? heading,
|
|
VoidCallback? onInfoTap,
|
|
}) {
|
|
return showModalBottomSheet<ImageSource>(
|
|
context: context,
|
|
builder: (context) => SafeArea(
|
|
child: Wrap(
|
|
children: [
|
|
if (heading != null)
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 8, 4),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
heading,
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.labelLarge
|
|
?.copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant),
|
|
),
|
|
),
|
|
if (onInfoTap != null)
|
|
IconButton(
|
|
icon: const Icon(Icons.info_outline),
|
|
iconSize: 20,
|
|
tooltip: 'Where do I find this?',
|
|
onPressed: onInfoTap,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
ListTile(
|
|
leading: const Icon(Icons.camera_alt_outlined),
|
|
title: const Text('Take Photo'),
|
|
onTap: () => Navigator.of(context).pop(ImageSource.camera),
|
|
),
|
|
ListTile(
|
|
leading: const Icon(Icons.photo_library_outlined),
|
|
title: const Text('Choose from Gallery'),
|
|
onTap: () => Navigator.of(context).pop(ImageSource.gallery),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|