MO-Fuel-Tax-Back/lib/screens/receipt_image_screen.dart

103 lines
2.7 KiB
Dart

import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/app_state.dart';
/// Full-screen, pinch-zoomable view of a receipt photo. Pass
/// [localImagePath] for a receipt still held locally, or [driveFileId] for
/// one already uploaded to the cloud 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 provider = context.read<AppState>().activeProvider;
if (provider == null) {
setState(() {
_error = 'Not connected to a cloud storage provider.';
_loading = false;
});
return;
}
final session = provider.beginSession();
try {
final bytes = await session.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 {
session.close();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
backgroundColor: Colors.black,
foregroundColor: Colors.white,
title: const Text('Receipt'),
),
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();
}
}