Files
fanuzu/app/lib/features/my/photo_picker.dart

44 lines
1.8 KiB
Dart

import 'package:image_picker/image_picker.dart';
import 'my_data.dart';
/// 사진을 어디서 가져오는가 — Figma `374:15486` 「앨범 항목」과 카메라 칸.
enum PhotoSource { gallery, camera }
/// 사진 한 장을 고르는 일. 화면이 이 함수를 주입받는다.
///
/// 플러그인을 화면 안에서 직접 부르면 위젯 테스트가 플랫폼 채널을 타서 돌지
/// 않는다. 고르는 일만 밖으로 빼면 화면은 「골라진 사진」만 다루면 된다.
typedef PhotoPicker = Future<PickedPhoto?> Function(PhotoSource source);
/// 기본 구현 — `image_picker`.
///
/// 앨범·카메라 권한 문구는 iOS `Info.plist` 의 `NSPhotoLibraryUsageDescription`·
/// `NSCameraUsageDescription` 에 이미 들어가 있다(BUILD.md 「권한 사용 문구 6종」).
/// 문구가 없으면 권한을 묻는 순간 앱이 종료되므로 여기서 다시 확인해 둔다.
Future<PickedPhoto?> pickPhotoWithPlugin(PhotoSource source) async {
final file = await ImagePicker().pickImage(
source: source == PhotoSource.camera
? ImageSource.camera
: ImageSource.gallery,
);
if (file == null) return null;
final bytes = await file.readAsBytes();
return PickedPhoto(
bytes: bytes,
// 플러그인이 종류를 주지 않는 기기가 있어 확장자로 물러난다.
contentType: file.mimeType ?? _typeOfName(file.name),
name: file.name,
);
}
String _typeOfName(String name) {
final lower = name.toLowerCase();
if (lower.endsWith('.png')) return 'image/png';
if (lower.endsWith('.webp')) return 'image/webp';
if (lower.endsWith('.gif')) return 'image/gif';
if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) return 'image/jpeg';
// 모르는 확장자는 지어내지 않는다. `checkProfilePhoto` 가 형식으로 거른다.
return 'application/octet-stream';
}