Added Google Drive storage location
This commit is contained in:
parent
e630f2a3ec
commit
73a7c93e64
22 changed files with 1690 additions and 205 deletions
|
|
@ -1,12 +1,67 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
/// Full-screen, pinch-zoomable view of a saved receipt photo.
|
||||
class ReceiptImageScreen extends StatelessWidget {
|
||||
final String imagePath;
|
||||
import '../services/app_state.dart';
|
||||
import '../services/drive_service.dart';
|
||||
|
||||
const ReceiptImageScreen({super.key, required this.imagePath});
|
||||
/// Full-screen, pinch-zoomable view of a receipt photo. Pass
|
||||
/// [localImagePath] for a receipt still held locally, or [driveFileId] for
|
||||
/// one already uploaded to Drive and removed locally — in which case it's
|
||||
/// downloaded on demand (no local caching afterward).
|
||||
class ReceiptImageScreen extends StatefulWidget {
|
||||
final String? localImagePath;
|
||||
final String? driveFileId;
|
||||
|
||||
const ReceiptImageScreen({super.key, this.localImagePath, this.driveFileId})
|
||||
: assert(localImagePath != null || driveFileId != null,
|
||||
'Must provide either a local path or a Drive file ID');
|
||||
|
||||
@override
|
||||
State<ReceiptImageScreen> createState() => _ReceiptImageScreenState();
|
||||
}
|
||||
|
||||
class _ReceiptImageScreenState extends State<ReceiptImageScreen> {
|
||||
Uint8List? _downloadedBytes;
|
||||
bool _loading = false;
|
||||
String? _error;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.driveFileId != null) {
|
||||
_download();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _download() async {
|
||||
setState(() {
|
||||
_loading = true;
|
||||
_error = null;
|
||||
});
|
||||
|
||||
final authService = context.read<AppState>().driveAuth;
|
||||
final client = authService.authenticatedHttpClient();
|
||||
try {
|
||||
final drive = DriveService(client);
|
||||
final bytes = await drive.downloadFileBytes(widget.driveFileId!);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_downloadedBytes = Uint8List.fromList(bytes);
|
||||
_loading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_error = 'Could not download receipt: $e';
|
||||
_loading = false;
|
||||
});
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -17,11 +72,26 @@ class ReceiptImageScreen extends StatelessWidget {
|
|||
foregroundColor: Colors.white,
|
||||
title: const Text('Receipt'),
|
||||
),
|
||||
body: Center(
|
||||
child: InteractiveViewer(
|
||||
child: Image.file(File(imagePath)),
|
||||
),
|
||||
),
|
||||
body: Center(child: _buildBody()),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
if (widget.localImagePath != null) {
|
||||
return InteractiveViewer(child: Image.file(File(widget.localImagePath!)));
|
||||
}
|
||||
if (_loading) {
|
||||
return const CircularProgressIndicator(color: Colors.white);
|
||||
}
|
||||
if (_error != null) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Text(_error!, style: const TextStyle(color: Colors.white)),
|
||||
);
|
||||
}
|
||||
if (_downloadedBytes != null) {
|
||||
return InteractiveViewer(child: Image.memory(_downloadedBytes!));
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue