feat(app): allow configurable and accessible audio storage folder (#4702)
TH
3d ago+444+444+012345678901234567890123456789-20-20-01234567890123456789
Summary
Fixes #4702
Allows users to configure an accessible storage directory (such as Music/Omi or Documents/Omi) for batch audio recordings instead of being restricted to sandboxed app documents storage (Android/data/com.friend.ios/), which is inaccessible in modern Android (API 30+) Scoped Storage without ADB/root.
Key Changes
- Configurable Storage Preference: Added
customAudioStorageDirgetter/setter onSharedPreferencesUtilinapp/lib/backend/preferences.dart. - Precedence Resolution: Added
resolveBatchAudioDirectoryPath(...)(pure precedence engine),resolveEffectiveBatchAudioDirectory()(async runtime resolver), andsetCustomAudioStorageDirectory()(atomic preference updater with fallback synchronization) inapp/lib/utils/batch_recording.dart. - Capture Controller Hardening: Replaced unconditional directory overwrites in
CaptureController(setBatchMode,_initiateDeviceAudioStreaming, and_startPhoneMicBatch) to useresolveEffectiveBatchAudioDirectory(). - Local Recordings & Playback Integration:
- Updated
LocalRecordingsProvider._dir()to scan the effective batch audio directory. - Updated
Wal.getFilePath()inwal.dartto inspectcustomAudioStorageDirandbatchAudioDirbefore falling back togetApplicationDocumentsDirectory(), ensuring uninterrupted playback and waveform generation.
- Updated
- Transcribe Later Settings UI: Added an "Audio Storage Folder" section in the Transcribe Later modal sheet (
app/lib/pages/settings/profile.dart) featuring the active folder path, a folder picker (FilePicker.platform.getDirectoryPath), and a reset action.
Verification & Testing
- Unit Tests (
test/unit/batch_audio_directory_resolution_test.dart):- Pure precedence resolution (custom > configured > default).
- Blank/whitespace string handling.
- Filesystem existence checks and automatic fallback.
- Setting and resetting custom audio storage directories.
LocalRecordingsProviderdiscovery of files in custom storage.Wal.getFilePath()resolution across custom and fallback locations.
- Widget Tests (
test/widgets/audio_storage_folder_sheet_test.dart):- Verified UI rendering of current storage folder.
- Verified folder change interaction and reset-to-default button behavior.
- Regression Tests:
test/unit/local_recordings_owner_test.dart(5/5 passed).test/unit/local_recordings_auto_upload_test.dart(14/14 passed).
- Static Analysis & Preflight:
flutter analyzeon touched/new files: 0 issues found.scripts/pr-preflight: 20/20 checks passed cleanly.
Failure-Class: none
PayPal: rwilcox413@gmail.com