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

@@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/data/core_repository.dart';
import 'package:flux/core/layout/app_shell.dart';
import 'package:flux/core/utils/extensions.dart';
import 'package:flux/core/widgets/set_password_screen.dart';
import 'package:flux/core/widgets/shared_forms/mobile_upload_screen.dart';
import 'package:flux/core/widgets/shared_forms/upload_success_screen.dart';
@@ -285,6 +284,7 @@ class AppRouter {
builder: (context, state) {
final typeString = state.pathParameters['type']!;
final id = state.pathParameters['id']!;
final companyId = state.uri.queryParameters['companyId']!;
// Trasformiamo la stringa dell'URL nel nostro amato Enum!
final parentType = AttachmentParentType.values.firstWhere(
@@ -297,8 +297,9 @@ class AppRouter {
return BlocProvider(
create: (context) =>
AttachmentsBloc(parentId: id, parentType: parentType),
child: const SharedMobileUploadScreen(
child: SharedMobileUploadScreen(
title: 'Caricamento Rapido',
companyId: companyId,
),
);
},

View File

@@ -4,6 +4,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/widgets/qr_upload_dialog.dart';
import 'package:flux/features/attachments/data/attachments_repository.dart';
import 'package:flux/features/attachments/ui/attachment_viewer_screen.dart';
import 'package:flux/features/attachments/ui/quick_rename_dialog.dart';
@@ -30,14 +32,16 @@ class _ExportItem {
class SharedAttachmentsSection extends StatefulWidget {
final String? parentId;
final String customerDisplayName;
final String titleForUpload;
final AttachmentParentType parentType;
final Future<String?> Function()? onGenerateIdForQr;
const SharedAttachmentsSection({
super.key,
this.parentId,
this.customerDisplayName = 'Cliente_sconosciuto',
this.titleForUpload = 'Cliente_sconosciuto',
required this.parentType,
this.onGenerateIdForQr,
});
@override
@@ -65,7 +69,7 @@ class _SharedAttachmentsSectionState extends State<SharedAttachmentsSection> {
Future<void> _selectExportDirectory() async {
final String? selectedDirectory = await FilePicker.getDirectoryPath(
dialogTitle: 'Seleziona la cartella di esportazione per TIM/Citrix',
dialogTitle: 'Seleziona la cartella di esportazione',
);
if (selectedDirectory != null) {
@@ -189,7 +193,7 @@ class _SharedAttachmentsSectionState extends State<SharedAttachmentsSection> {
} else {
// Se sono più file uniti
suggestedName = '${widget.customerDisplayName}_Unito';
suggestedName = '${widget.titleForUpload}_Unito';
}
if (!mounted) return;
@@ -397,7 +401,6 @@ class _SharedAttachmentsSectionState extends State<SharedAttachmentsSection> {
Widget build(BuildContext context) {
final theme = Theme.of(context);
// USIAMO IL TUO BLOC!
return BlocBuilder<AttachmentsBloc, AttachmentsState>(
builder: (context, state) {
final allFiles = state.allFiles;
@@ -421,7 +424,7 @@ class _SharedAttachmentsSectionState extends State<SharedAttachmentsSection> {
color: theme.colorScheme.primary,
),
title: const Text(
'Cartella Export (Es. Citrix TIM)',
'Cartella Export (Es. TIM AttachmentRepository)',
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(
@@ -451,6 +454,69 @@ class _SharedAttachmentsSectionState extends State<SharedAttachmentsSection> {
onPressed: state.status == AttachmentsStatus.uploading
? null
: _pickFiles,
/* : () {
final bloc = context.read<AttachmentsBloc>();
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => BlocProvider.value(
value: bloc,
child: SharedMobileUploadScreen(
title: widget.titleForUpload,
),
),
),
);
}, */
),
const SizedBox(width: 8),
Tooltip(
message: 'Carica foto con lo smartphone',
child: IconButton(
icon: const Icon(Icons.qr_code_scanner),
color: theme.colorScheme.primary, // Sempre colorato!
onPressed: () async {
String? targetId = state.parentId;
// SE L'ID NON C'È, CHIAMIAMO IL SALVATAGGIO IN BACKGROUND!
if (targetId == null) {
if (widget.onGenerateIdForQr != null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Salvataggio rapido scheda in corso... ⏳',
),
duration: Duration(seconds: 1),
),
);
// Aspettiamo che il TicketFormCubit faccia il suo lavoro
targetId = await widget.onGenerateIdForQr!();
}
// Se fallisce (es. validazione form non passata), ci fermiamo
if (targetId == null) return;
}
// GENERAZIONE DEL DEEP LINK AGNOSTICO
final companyId = GetIt.I
.get<SessionCubit>()
.state
.company!
.id!;
final deepLink =
'https://flux.catelli.it/upload/${state.parentType.name}/$targetId?companyId=$companyId';
if (context.mounted) {
showDialog(
context: context,
builder: (_) => QrUploadDialog(
deepLinkUrl: deepLink,
title: 'Carica File: ${widget.titleForUpload}',
),
);
}
},
),
),
const SizedBox(width: 12),

View File

@@ -8,8 +8,13 @@ import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
class SharedMobileUploadScreen extends StatefulWidget {
final String title;
final String companyId;
const SharedMobileUploadScreen({super.key, required this.title});
const SharedMobileUploadScreen({
super.key,
required this.title,
required this.companyId,
});
@override
State<SharedMobileUploadScreen> createState() =>
@@ -290,7 +295,10 @@ class _SharedMobileUploadScreenState extends State<SharedMobileUploadScreen> {
}
Future<void> _handleFilePicker() async {
final result = await FilePicker.pickFiles(allowMultiple: true);
final result = await FilePicker.pickFiles(
allowMultiple: true,
withData: true,
);
if (result != null) {
setState(() {
_stagedFiles.addAll(result.files);
@@ -304,7 +312,10 @@ class _SharedMobileUploadScreenState extends State<SharedMobileUploadScreen> {
// Lanciamo l'evento del nostro nuovo AttachmentsBloc Agnostico!
context.read<AttachmentsBloc>().add(
UploadAttachmentsEvent(pickedFiles: _stagedFiles),
UploadAttachmentsEvent(
pickedFiles: _stagedFiles,
companyId: widget.companyId,
),
);
}
}

View File

@@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/core/widgets/qr_upload_dialog.dart';
import 'package:flux/core/widgets/shared_forms/mobile_upload_screen.dart';
import 'package:flux/features/attachments/blocs/attachments_bloc.dart';
import 'package:get_it/get_it.dart';
class SharedFilesSection extends StatelessWidget {
final String titleNameForUpload;
@@ -64,8 +66,13 @@ class SharedFilesSection extends StatelessWidget {
}
// GENERAZIONE DEL DEEP LINK AGNOSTICO
final companyId = GetIt.I
.get<SessionCubit>()
.state
.company!
.id!;
final deepLink =
'https://flux.catelli.it/upload/${state.parentType.name}/$targetId';
'https://flux.catelli.it/upload/${state.parentType.name}/$targetId?companyId=$companyId';
if (context.mounted) {
showDialog(
@@ -93,6 +100,11 @@ class SharedFilesSection extends StatelessWidget {
value: bloc,
child: SharedMobileUploadScreen(
title: titleNameForUpload,
companyId: GetIt.I
.get<SessionCubit>()
.state
.company!
.id!,
),
),
),