Files
plezy/lib/services/file_picker_service.dart
T
2026-04-20 20:17:57 +02:00

63 lines
1.7 KiB
Dart

import 'package:file_picker/file_picker.dart';
import 'package:flutter/services.dart';
import '../utils/app_logger.dart';
/// Serializes file_picker invocations to avoid
/// `PlatformException(already_active, File picker is already active)`.
class FilePickerService {
static final FilePickerService _instance = FilePickerService._();
static FilePickerService get instance => _instance;
FilePickerService._();
bool _active = false;
Future<T?> _guard<T>(String opName, Future<T?> Function() body) async {
if (_active) return null;
_active = true;
try {
return await body();
} on PlatformException catch (e, st) {
if (e.code == 'already_active') return null;
appLogger.e('FilePicker.$opName failed', error: e, stackTrace: st);
rethrow;
} finally {
_active = false;
}
}
Future<FilePickerResult?> pickFiles({
FileType type = FileType.any,
List<String>? allowedExtensions,
bool withData = false,
}) {
return _guard(
'pickFiles',
() => FilePicker.platform.pickFiles(type: type, allowedExtensions: allowedExtensions, withData: withData),
);
}
Future<String?> getDirectoryPath({String? dialogTitle}) {
return _guard('getDirectoryPath', () => FilePicker.platform.getDirectoryPath(dialogTitle: dialogTitle));
}
Future<String?> saveFile({
String? dialogTitle,
String? fileName,
Uint8List? bytes,
FileType type = FileType.any,
List<String>? allowedExtensions,
}) {
return _guard(
'saveFile',
() => FilePicker.platform.saveFile(
dialogTitle: dialogTitle,
fileName: fileName,
bytes: bytes,
type: type,
allowedExtensions: allowedExtensions,
),
);
}
}