fix mobile upload

This commit is contained in:
2026-05-09 09:50:20 +02:00
parent c6ef798b22
commit 65aa3c7de8
11 changed files with 164 additions and 52 deletions

View File

@@ -14,6 +14,7 @@ part 'attachments_state.dart';
class AttachmentsBloc extends Bloc<AttachmentsEvent, AttachmentsState> {
final _repository = GetIt.I.get<AttachmentsRepository>();
final String? companyId = GetIt.I.get<SessionCubit>().state.company?.id;
AttachmentsBloc({String? parentId, required AttachmentParentType parentType})
: super(
@@ -36,7 +37,7 @@ class AttachmentsBloc extends Bloc<AttachmentsEvent, AttachmentsState> {
on<ClearAttachmentSelectionEvent>(_onClearAttachmentSelection);
// Se il BLoC nasce già con un ID, carichiamo i file
if (parentId != null) {
if (parentId != null && companyId != null) {
add(LoadAttachmentsEvent(parentId: parentId));
}
}
@@ -65,6 +66,7 @@ class AttachmentsBloc extends Bloc<AttachmentsEvent, AttachmentsState> {
parentId: event.newParentId,
parentType: state.parentType,
pickedFile: fakePlatformFile,
companyId: companyId!,
);
}).toList();
@@ -118,12 +120,11 @@ class AttachmentsBloc extends Bloc<AttachmentsEvent, AttachmentsState> {
// BIVIO 1: PRATICA NUOVA (Salvataggio locale)
if (currentId == null) {
final companyId = GetIt.I.get<SessionCubit>().state.company!.id!;
final newLocalFiles = event.files.map((file) {
// Assegniamo i campi dinamicamente in base al parentType!
return AttachmentModel(
id: null,
companyId: companyId,
companyId: companyId!,
operationId: state.parentType == AttachmentParentType.operation
? ''
: null,
@@ -156,6 +157,7 @@ class AttachmentsBloc extends Bloc<AttachmentsEvent, AttachmentsState> {
parentId: currentId,
parentType: state.parentType,
pickedFile: file,
companyId: companyId!,
);
}).toList();
@@ -191,6 +193,7 @@ class AttachmentsBloc extends Bloc<AttachmentsEvent, AttachmentsState> {
parentId: state.parentId!,
parentType: state.parentType,
pickedFile: file,
companyId: event.companyId,
),
);
}
@@ -216,6 +219,7 @@ class AttachmentsBloc extends Bloc<AttachmentsEvent, AttachmentsState> {
parentId: state.parentId!,
parentType: state.parentType,
pickedFile: fakePlatformFile,
companyId: companyId!,
),
);
}

View File

@@ -29,7 +29,12 @@ class AddAttachmentsEvent extends AttachmentsEvent {
class UploadAttachmentsEvent extends AttachmentsEvent {
final List<PlatformFile>? pickedFiles;
final List<XFile>? photos;
const UploadAttachmentsEvent({this.pickedFiles, this.photos});
final String companyId;
const UploadAttachmentsEvent({
this.pickedFiles,
this.photos,
required this.companyId,
});
}
class DeleteAttachmentsEvent extends AttachmentsEvent {}

View File

@@ -16,6 +16,7 @@ class AttachmentsState extends Equatable {
final AttachmentParentType parentType;
final AttachmentsStatus status;
final String? error;
final List<AttachmentModel> localFiles;
final List<AttachmentModel> remoteFiles;
final List<AttachmentModel> selectedFiles;

View File

@@ -3,8 +3,6 @@ import 'package:file_picker/file_picker.dart';
import 'package:flux/features/attachments/models/attachment_model.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
import 'package:get_it/get_it.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
class AttachmentsRepository {
final _supabase = Supabase.instance.client;
@@ -58,9 +56,9 @@ class AttachmentsRepository {
required String parentId,
required AttachmentParentType parentType,
required PlatformFile pickedFile,
required String companyId,
}) async {
try {
final companyId = GetIt.I.get<SessionCubit>().state.company!.id!;
final extension = pickedFile.extension ?? pickedFile.name.split('.').last;
final cleanName = pickedFile.name
.replaceAll(RegExp(r'[^\w\s\.-]'), '')

View File

@@ -9,6 +9,7 @@ import 'package:flux/core/widgets/qr_upload_dialog.dart';
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
import 'package:flux/features/attachments/models/attachment_model.dart';
import 'package:flux/features/customers/models/customer_model.dart';
import 'package:get_it/get_it.dart';
class CustomerDetailScreen extends StatefulWidget {
final CustomerModel customer;
@@ -43,7 +44,12 @@ class _CustomerDetailScreenState extends State<CustomerDetailScreen> {
if (result != null) {
try {
attachmentsBloc.add(UploadAttachmentsEvent(pickedFiles: result.files));
attachmentsBloc.add(
UploadAttachmentsEvent(
pickedFiles: result.files,
companyId: GetIt.I.get<SessionCubit>().state.company!.id!,
),
);
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/widgets/shared_forms/shared_files_section.dart';
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
import 'package:flux/features/operations/blocs/operation_form_cubit.dart';
import 'package:flux/features/operations/models/operation_model.dart';
@@ -246,10 +245,12 @@ class _OperationFormScreenState extends State<OperationFormScreen> {
flex: 3,
child: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: SharedFilesSection(
titleNameForUpload:
child: SharedAttachmentsSection(
parentType: AttachmentParentType.operation,
parentId: state.operation.id,
titleForUpload:
state.operation.customerDisplayName ??
'Nuova operazione',
'Nuova pratica',
onGenerateIdForQr: _generateIdForQr,
),
),
@@ -408,9 +409,9 @@ class _OperationFormScreenState extends State<OperationFormScreen> {
color: _getStatusColor(displayStatus),
),
items: OperationStatus.values
.where(
/* .where(
(s) => s != OperationStatus.draft,
) // Nascondiamo 'Bozza' dal menu
) // Nascondiamo 'Bozza' dal menu */
.map(
(status) => DropdownMenuItem(
value: status,
@@ -456,7 +457,7 @@ class _OperationFormScreenState extends State<OperationFormScreen> {
),
const Divider(height: 32),
_buildSectionTitle('Cliente & Riferimento'),
//_buildSectionTitle('Cliente & Riferimento'),
SharedCustomerSection(
customerId: currentOp.customerId,
customerName: currentOp.customerDisplayName,
@@ -539,15 +540,18 @@ class _OperationFormScreenState extends State<OperationFormScreen> {
const Divider(height: 32),
if (showFiles) ...[
/* SharedAttachmentsSection(
SharedAttachmentsSection(
parentType: AttachmentParentType.operation,
parentId: currentOp.id,
), */
SharedFilesSection(
titleNameForUpload:
titleForUpload:
state.operation.customerDisplayName ?? 'Nuova pratica',
onGenerateIdForQr: _generateIdForQr,
),
/* SharedFilesSection(
titleNameForUpload:
state.operation.customerDisplayName ?? 'Nuova pratica',
onGenerateIdForQr: _generateIdForQr,
), */
],
],
);

View File

@@ -45,6 +45,7 @@ class DetailsSection extends StatelessWidget {
}
void _showProviderModal(BuildContext context, String operationType) {
final OperationFormCubit cubit = context.read<OperationFormCubit>();
showModalBottomSheet(
context: context,
isScrollControlled: true,
@@ -103,28 +104,31 @@ class DetailsSection extends StatelessWidget {
);
}
return ListView.builder(
controller: scrollController,
itemCount: filteredProviders.length,
itemBuilder: (context, index) {
final provider = filteredProviders[index];
return ListTile(
leading: const Icon(Icons.business),
title: Text(
provider.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
return BlocProvider.value(
value: cubit,
child: ListView.builder(
controller: scrollController,
itemCount: filteredProviders.length,
itemBuilder: (context, index) {
final provider = filteredProviders[index];
return ListTile(
leading: const Icon(Icons.business),
title: Text(
provider.name,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
),
onTap: () {
context.read<OperationFormCubit>().updateFields(
providerId: provider.id,
providerDisplayName: provider.name,
);
Navigator.pop(modalContext);
},
);
},
onTap: () {
context.read<OperationFormCubit>().updateFields(
providerId: provider.id,
providerDisplayName: provider.name,
);
Navigator.pop(modalContext);
},
);
},
),
);
},
),