Reviewed-on: #12 Co-authored-by: Mark M2 Macbook <marco@catelli.it> Co-committed-by: Mark M2 Macbook <marco@catelli.it>
140 lines
4.3 KiB
Dart
140 lines
4.3 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
import 'package:file_picker/file_picker.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:equatable/equatable.dart';
|
|
import 'package:flux/features/attachments/models/attachment_model.dart';
|
|
import 'package:flux/features/customers/data/customer_repository.dart';
|
|
import 'package:get_it/get_it.dart';
|
|
|
|
part 'customer_files_events.dart';
|
|
part 'customer_files_state.dart';
|
|
|
|
class CustomerFilesBloc extends Bloc<CustomerFilesEvent, CustomerFilesState> {
|
|
final CustomerRepository _repository = GetIt.I<CustomerRepository>();
|
|
final String customerId;
|
|
CustomerFilesBloc(this.customerId)
|
|
: super(const CustomerFilesState(status: CustomerFilesStatus.initial)) {
|
|
on<LoadCustomerFilesEvent>(_loadCustomerFiles);
|
|
on<UploadCustomerFileEvent>(_uploadCustomerFile);
|
|
on<UploadMultipleCustomerFilesEvent>(_uploadMultipleCustomerFiles);
|
|
on<DeleteCustomerFilesEvent>(_deleteCustomerFiles);
|
|
on<ToggleCustomerFileSelectionEvent>(_toggleCustomerFileSelection);
|
|
}
|
|
void _loadCustomerFiles(
|
|
LoadCustomerFilesEvent event,
|
|
Emitter<CustomerFilesState> emit,
|
|
) async {
|
|
await emit.forEach<List<AttachmentModel>>(
|
|
_repository.getCustomerFilesStream(customerId),
|
|
onData: (customerFiles) => CustomerFilesState(
|
|
status: CustomerFilesStatus.success,
|
|
customerFiles: customerFiles,
|
|
),
|
|
onError: (error, stackTrace) => CustomerFilesState(
|
|
status: CustomerFilesStatus.failure,
|
|
error: error.toString(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _uploadCustomerFile(
|
|
UploadCustomerFileEvent event,
|
|
Emitter<CustomerFilesState> emit,
|
|
) async {
|
|
emit(state.copyWith(status: CustomerFilesStatus.uploading));
|
|
if (event.pickedFile != null) {
|
|
try {
|
|
await _repository.uploadAndRegisterFile(
|
|
customerId: customerId,
|
|
pickedFile: event.pickedFile!,
|
|
);
|
|
emit(state.copyWith(status: CustomerFilesStatus.success));
|
|
} catch (e) {
|
|
emit(
|
|
state.copyWith(
|
|
status: CustomerFilesStatus.failure,
|
|
error: e.toString(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
FutureOr<void> _uploadMultipleCustomerFiles(
|
|
UploadMultipleCustomerFilesEvent event,
|
|
Emitter<CustomerFilesState> emit,
|
|
) async {
|
|
if (event.files.isEmpty) {
|
|
emit(
|
|
state.copyWith(
|
|
status: CustomerFilesStatus.failure,
|
|
error: "Nessun file selezionato",
|
|
),
|
|
);
|
|
return;
|
|
}
|
|
emit(state.copyWith(status: CustomerFilesStatus.uploading, error: null));
|
|
try {
|
|
// 2. Creiamo una lista di "Promesse" (Futures) per il repository
|
|
final List<Future<void>> uploadTasks = [];
|
|
for (var file in event.files) {
|
|
// Aggiungiamo il task alla lista, ma NON usiamo await qui dentro!
|
|
uploadTasks.add(
|
|
_repository.uploadAndRegisterFile(
|
|
customerId: customerId,
|
|
pickedFile: file,
|
|
),
|
|
);
|
|
}
|
|
// 3. ESECUZIONE PARALLELA!
|
|
// Aspettiamo che tutti i file siano caricati contemporaneamente.
|
|
await Future.wait(uploadTasks);
|
|
// 4. GRAN FINALE: Tutto caricato, emettiamo il success!
|
|
emit(state.copyWith(status: CustomerFilesStatus.success));
|
|
} catch (e) {
|
|
// Se anche un solo file fallisce, catturiamo l'errore
|
|
emit(
|
|
state.copyWith(
|
|
status: CustomerFilesStatus.failure,
|
|
error: "Errore durante l'upload multiplo: $e",
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> _deleteCustomerFiles(
|
|
DeleteCustomerFilesEvent event,
|
|
Emitter<CustomerFilesState> emit,
|
|
) async {
|
|
emit(state.copyWith(status: CustomerFilesStatus.loading));
|
|
try {
|
|
await _repository.deleteDocuments(state.selectedFiles);
|
|
emit(
|
|
state.copyWith(status: CustomerFilesStatus.success, selectedFiles: []),
|
|
);
|
|
} catch (e) {
|
|
emit(
|
|
state.copyWith(
|
|
status: CustomerFilesStatus.failure,
|
|
error: e.toString(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _toggleCustomerFileSelection(
|
|
ToggleCustomerFileSelectionEvent event,
|
|
Emitter<CustomerFilesState> emit,
|
|
) {
|
|
List<AttachmentModel> selectedFiles = List.from(state.selectedFiles);
|
|
if (selectedFiles.contains(event.file)) {
|
|
selectedFiles.remove(event.file);
|
|
} else {
|
|
selectedFiles.add(event.file);
|
|
}
|
|
emit(state.copyWith(selectedFiles: selectedFiles));
|
|
}
|
|
}
|