/// 약속 (M3 VaultLocation): 암호 보관함이 쓰는 자리 셋 - 보관함 폴더 · [보기] 로 잠깐 푼 파일을 두는 곳 · [꺼내기] 받을 폴더 고르기. /// 입력: 없음 (자리를 묻는 함수 셋). 출력: 폴더 (없으면 부르는 쪽이 만든다) · 고른 폴더 (취소면 null). 오류: 기기 자리를 못 얻으면 그 오류. /// [VaultLocation.device] = 실제 자리 (앱 조립 PlatformServices.create 가 씀): /// 보관함 - Android Download/JJ_MKVMaker/vault · Windows 문서\JJ_MKVMaker\vault, /// 푼 파일 - 앱 전용 (Android getCacheDir · Windows 앱 데이터 폴더의 temp - 공유 폴더가 아님, 관리자 10/21), 고르기 - 파일 고르기 창. /// [VaultLocation.under] = 앱 임시 폴더 아래 (PlatformServices 를 손으로 조립할 때의 처음 값 - 사용자 보관함 · 앱 데이터를 건드리지 않음). /// 예전의 바꿀 수 있는 전역 함수 vaultDirOf · vaultViewRootOf · vaultPickFolder 를 대신한다 (설계 M3) library; import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/services.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; class VaultLocation { /// 보관함 폴더 final Future Function() vaultDir; /// [보기] 로 잠깐 푼 파일 · 꺼내기 기록을 두는 곳 final Future Function() viewRoot; /// [꺼내기] 받을 폴더 고르기 (취소면 null) final Future Function() pickFolder; const VaultLocation({required this.vaultDir, required this.viewRoot, required this.pickFolder}); /// 이 기기의 실제 자리 static final device = VaultLocation( vaultDir: () async { if (Platform.isAndroid) { final root = await const MethodChannel('jj_mkvmaker/android').invokeMethod('storageRoot') ?? '/storage/emulated/0'; return Directory(p.join(root, 'Download', 'JJ_MKVMaker', 'vault')); } return Directory(p.join((await getApplicationDocumentsDirectory()).path, 'JJ_MKVMaker', 'vault')); }, viewRoot: () async { if (Platform.isAndroid) return getTemporaryDirectory(); return Directory(p.join((await getApplicationSupportDirectory()).path, 'temp')); }, pickFolder: () => FilePicker.getDirectoryPath(), ); /// [tempDir] (앱 임시 폴더) 아래의 vault · vault_view. 고르기는 없음 (null) factory VaultLocation.under(Future Function() tempDir) => VaultLocation( vaultDir: () async => Directory(p.join(await tempDir(), 'vault')), viewRoot: () async => Directory(p.join(await tempDir(), 'vault_view')), pickFolder: () async => null, ); }