feat-add-files-from-qr #8

Merged
brontomark merged 13 commits from feat-add-files-from-qr into main 2026-04-26 10:15:35 +02:00
4 changed files with 73 additions and 14 deletions
Showing only changes of commit de431b6ee6 - Show all commits

View File

@@ -128,7 +128,29 @@ class ServiceFilesBloc extends Bloc<ServiceFilesEvent, ServiceFilesState> {
FutureOr<void> _onUploadServiceFiles(
UploadServiceFilesEvent event,
Emitter<ServiceFilesState> emit,
) {}
) async {
if (event.pickedFiles == null && event.photos == null) return;
if (event.pickedFiles!.isEmpty && event.photos!.isEmpty) return;
// BIVIO 2: PRATICA ESISTENTE (Abbiamo l'ID
emit(state.copyWith(status: ServiceFilesStatus.uploading));
try {
// Logica identica a quella che abbiamo fatto per i clienti
if (event.pickedFiles != null && event.pickedFiles!.isNotEmpty) {
for (var file in event.pickedFiles!) {
await _repository.uploadAndRegisterServiceFile(
serviceId: serviceId!,
pickedFile: file,
);
}
}
emit(state.copyWith(status: ServiceFilesStatus.success));
} catch (e) {
emit(
state.copyWith(status: ServiceFilesStatus.failure, error: e.toString()),
);
}
}
FutureOr<void> _onDeleteServiceFiles(
DeleteServiceFilesEvent event,

View File

@@ -33,12 +33,12 @@ class AddServiceFilesEvent extends ServiceFilesEvent {
}
class UploadServiceFilesEvent extends ServiceFilesEvent {
final PlatformFile? pickedFile;
final File? photo;
const UploadServiceFilesEvent({this.pickedFile, this.photo});
final List<PlatformFile>? pickedFiles;
final List<File>? photos;
const UploadServiceFilesEvent({this.pickedFiles, this.photos});
@override
List<Object?> get props => [pickedFile, photo];
List<Object?> get props => [pickedFiles, photos];
}
class DeleteServiceFilesEvent extends ServiceFilesEvent {}

View File

@@ -308,7 +308,7 @@ class AttachmentsSection extends StatelessWidget {
},
child: QrUploadDialog(
deepLinkUrl:
'fluxapp://service/${currentService!.id}/upload?name=${Uri.encodeComponent(nomePratica)}',
'fluxapp:///service/${currentService!.id}/upload?name=${Uri.encodeComponent(nomePratica)}',
title: 'Scatta per\n$nomePratica',
),
),

View File

@@ -5,7 +5,7 @@ import 'package:image_picker/image_picker.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flux/features/services/blocs/service_files_bloc.dart';
class ServiceMobileUploadScreen extends StatelessWidget {
class ServiceMobileUploadScreen extends StatefulWidget {
final String serviceId;
final String serviceName;
@@ -15,6 +15,15 @@ class ServiceMobileUploadScreen extends StatelessWidget {
required this.serviceName,
});
@override
State<ServiceMobileUploadScreen> createState() =>
_ServiceMobileUploadScreenState();
}
class _ServiceMobileUploadScreenState extends State<ServiceMobileUploadScreen> {
final List<PlatformFile> _pickedFiles = [];
final List<File> _photos = [];
@override
Widget build(BuildContext context) {
return BlocListener<ServiceFilesBloc, ServiceFilesState>(
@@ -31,7 +40,7 @@ class ServiceMobileUploadScreen extends StatelessWidget {
}
},
child: Scaffold(
appBar: AppBar(title: Text("Upload Pratica:\n$serviceName")),
appBar: AppBar(title: Text("Upload Pratica:\n${widget.serviceName}")),
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
@@ -74,6 +83,27 @@ class ServiceMobileUploadScreen extends StatelessWidget {
),
),
),
const SizedBox(height: 30),
SizedBox(
width: double.infinity,
height: 80,
child: ElevatedButton.icon(
onPressed: () => _handleSaveAndClose(context),
icon: const Icon(Icons.save_alt_rounded, size: 28),
label: const Text(
"INVIA E CHIUDI",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[200],
foregroundColor: Colors.black87,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
),
],
),
),
@@ -88,18 +118,25 @@ class ServiceMobileUploadScreen extends StatelessWidget {
imageQuality: 80,
);
if (photo != null && context.mounted) {
context.read<ServiceFilesBloc>().add(
UploadServiceFilesEvent(photo: File(photo.path)),
);
setState(() {
_photos.add(File(photo.path));
});
}
}
Future<void> _handleFilePicker(BuildContext context) async {
final result = await FilePicker.pickFiles(withData: true);
if (result != null && context.mounted) {
context.read<ServiceFilesBloc>().add(
UploadServiceFilesEvent(pickedFile: result.files.first),
);
setState(() {
_pickedFiles.addAll(result.files);
});
}
}
Future<void> _handleSaveAndClose(BuildContext context) async {
context.read<ServiceFilesBloc>().add(
UploadServiceFilesEvent(pickedFiles: _pickedFiles, photos: _photos),
);
Navigator.pop(context);
}
}