mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-04-02 23:21:52 +01:00
fix: building
This commit is contained in:
330
DOWNLOAD_SYSTEM_REFACTOR.md
Normal file
330
DOWNLOAD_SYSTEM_REFACTOR.md
Normal file
@@ -0,0 +1,330 @@
|
||||
# Download System Refactor - Summary
|
||||
|
||||
## Overview
|
||||
|
||||
The download system has been completely refactored to use a new native iOS module for background downloads, replacing the third-party library with a custom, streamlined solution.
|
||||
|
||||
## What Was Done
|
||||
|
||||
### 1. Created New Native Module (`BackgroundDownloader`)
|
||||
|
||||
**Location**: `modules/background-downloader/`
|
||||
|
||||
A complete Expo native module for iOS background file downloads:
|
||||
|
||||
- **Swift Implementation**: `BackgroundDownloaderModule.swift`
|
||||
- Uses `NSURLSession` with background configuration
|
||||
- Implements `URLSessionDownloadDelegate` for progress tracking
|
||||
- Handles iOS background session events via AppDelegate subscriber
|
||||
- Session ID: `com.fredrikburmester.streamyfin.backgrounddownloader`
|
||||
|
||||
- **TypeScript Interface**: Full type-safe API with events
|
||||
- `startDownload(url, destinationPath?)` - Start a download
|
||||
- `cancelDownload(taskId)` - Cancel a specific download
|
||||
- `cancelAllDownloads()` - Cancel all downloads
|
||||
- `getActiveDownloads()` - List active downloads
|
||||
|
||||
- **Events**:
|
||||
- `onDownloadProgress` - Progress updates with bytes/percentage
|
||||
- `onDownloadComplete` - Completion with file path
|
||||
- `onDownloadError` - Error handling
|
||||
- `onDownloadStarted` - Download initiation confirmation
|
||||
|
||||
- **Documentation**: Complete README with usage examples
|
||||
|
||||
### 2. Rewrote DownloadProvider
|
||||
|
||||
**Location**: `providers/DownloadProvider.tsx`
|
||||
|
||||
A simplified, focused implementation:
|
||||
|
||||
**Features Included**:
|
||||
- ✅ Video file downloads with progress tracking
|
||||
- ✅ Background download support
|
||||
- ✅ Database persistence (same format as before)
|
||||
- ✅ Movies and TV episodes support
|
||||
- ✅ Download notifications (success/error)
|
||||
- ✅ File deletion and management
|
||||
- ✅ Size calculation
|
||||
- ✅ Same context API for backward compatibility
|
||||
|
||||
**Features Removed (for simplicity)**:
|
||||
- ❌ Trickplay image downloads
|
||||
- ❌ Subtitle downloads
|
||||
- ❌ Queue management with concurrent limits
|
||||
- ❌ Pause/Resume (can be added back easily)
|
||||
- ❌ Download speed/ETA calculations
|
||||
- ❌ Cache directory management
|
||||
|
||||
**Key Improvements**:
|
||||
- Event-driven architecture (no polling)
|
||||
- Better background handling via native module
|
||||
- Cleaner, more maintainable code
|
||||
- Proper TypeScript typing throughout
|
||||
- Simplified state management
|
||||
|
||||
### 3. Preserved Old Implementation
|
||||
|
||||
**Location**: `providers/DownloadProvider.deprecated.tsx`
|
||||
|
||||
The old implementation has been preserved for reference but should not be used.
|
||||
|
||||
### 4. Documentation
|
||||
|
||||
Created comprehensive documentation:
|
||||
|
||||
- **Module README**: `modules/background-downloader/README.md`
|
||||
- API reference
|
||||
- Usage examples
|
||||
- Implementation details
|
||||
|
||||
- **Migration Guide**: `providers/Downloads/MIGRATION.md`
|
||||
- What changed
|
||||
- API compatibility matrix
|
||||
- Migration steps
|
||||
- Troubleshooting guide
|
||||
|
||||
- **System README**: `providers/Downloads/README.md`
|
||||
- Architecture overview
|
||||
- Type definitions
|
||||
- Usage examples
|
||||
- File storage details
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Background Download Implementation
|
||||
|
||||
The native module uses iOS's recommended approach:
|
||||
|
||||
1. **Background URLSession**: Persistent identifier ensures downloads continue
|
||||
2. **Delegate Pattern**: Progress and completion via delegate callbacks
|
||||
3. **AppDelegate Integration**: Handles system wake-ups for download events
|
||||
4. **Completion Handler**: Properly signals iOS when background work is done
|
||||
|
||||
### State Management
|
||||
|
||||
```typescript
|
||||
// Active downloads tracked in Jotai atom
|
||||
const processesAtom = atom<JobStatus[]>([]);
|
||||
|
||||
// Task ID to Process ID mapping for event correlation
|
||||
const taskMap = Map<number, string>();
|
||||
|
||||
// Persistent database in MMKV
|
||||
storage.set('downloads.v2.json', JSON.stringify(database));
|
||||
```
|
||||
|
||||
### Download Flow
|
||||
|
||||
```
|
||||
User initiates download
|
||||
↓
|
||||
Create JobStatus & add to processes
|
||||
↓
|
||||
Generate destination path
|
||||
↓
|
||||
Start native BackgroundDownloader
|
||||
↓
|
||||
Map taskId ↔ processId
|
||||
↓
|
||||
Receive progress events → Update UI
|
||||
↓
|
||||
Receive completion event
|
||||
↓
|
||||
Move file to permanent location
|
||||
↓
|
||||
Save to database
|
||||
↓
|
||||
Send notification
|
||||
↓
|
||||
Clean up process
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### iOS Background Modes
|
||||
|
||||
Already configured in `app.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"ios": {
|
||||
"infoPlist": {
|
||||
"UIBackgroundModes": ["audio", "fetch"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The "fetch" mode enables background URLSession downloads.
|
||||
|
||||
### Module Integration
|
||||
|
||||
The module is:
|
||||
- ✅ Auto-linked via Expo
|
||||
- ✅ Exported from `modules/index.ts`
|
||||
- ✅ Type-safe with full TypeScript support
|
||||
- ✅ Registered as AppDelegate subscriber
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### None for Normal Usage
|
||||
|
||||
The public API remains the same for the most common operations:
|
||||
|
||||
```typescript
|
||||
const {
|
||||
startBackgroundDownload,
|
||||
cancelDownload,
|
||||
getDownloadedItems,
|
||||
deleteFile,
|
||||
processes
|
||||
} = useDownload();
|
||||
```
|
||||
|
||||
### No-op Methods
|
||||
|
||||
These methods exist but do nothing (for compatibility):
|
||||
- `pauseDownload()`
|
||||
- `resumeDownload()`
|
||||
- `startDownload()` (use `startBackgroundDownload` instead)
|
||||
- `deleteFileByType()`
|
||||
- `cleanCacheDirectory()`
|
||||
- `updateDownloadedItem()`
|
||||
- `dumpDownloadDiagnostics()`
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
Before deployment, test:
|
||||
|
||||
- [ ] Download a movie
|
||||
- [ ] Download a TV episode
|
||||
- [ ] Download multiple items simultaneously
|
||||
- [ ] Cancel an active download
|
||||
- [ ] Delete a downloaded item
|
||||
- [ ] View list of downloads
|
||||
- [ ] Background the app during download
|
||||
- [ ] Force quit and restart (download should be cancelled)
|
||||
- [ ] Verify notifications appear
|
||||
- [ ] Check file integrity and playback
|
||||
- [ ] Verify database persistence
|
||||
- [ ] Check storage calculations
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Immediate
|
||||
|
||||
1. **Rebuild iOS app**:
|
||||
```bash
|
||||
npx expo prebuild -p ios
|
||||
cd ios && pod install && cd ..
|
||||
npx expo run:ios
|
||||
```
|
||||
|
||||
2. **Test thoroughly**: Use the testing checklist above
|
||||
|
||||
3. **Monitor for issues**: Check console logs and user reports
|
||||
|
||||
### Future Enhancements
|
||||
|
||||
Priority features to add back:
|
||||
|
||||
1. **Pause/Resume** (High Priority)
|
||||
- Easy to implement with NSURLSession
|
||||
- User-requested feature
|
||||
|
||||
2. **Queue Management** (Medium Priority)
|
||||
- Concurrent download limits
|
||||
- Automatic queue processing
|
||||
|
||||
3. **Progress Persistence** (Medium Priority)
|
||||
- Resume interrupted downloads after app restart
|
||||
- Save download state to database
|
||||
|
||||
4. **Trickplay & Subtitles** (Low Priority)
|
||||
- Re-add auxiliary file downloads
|
||||
- Integrate with video playback
|
||||
|
||||
5. **Download Analytics** (Low Priority)
|
||||
- Speed calculation
|
||||
- ETA estimation
|
||||
- Failure rate tracking
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **iOS Only**: Android support not yet implemented
|
||||
2. **No Pause**: Cannot pause/resume downloads yet
|
||||
3. **No Queue**: All downloads start immediately
|
||||
4. **Force Quit**: Downloads cancelled if app is force-quit (iOS limitation)
|
||||
5. **No Persistence**: Downloads lost if app crashes or is terminated
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
Over the old system:
|
||||
|
||||
- **Better Background Support**: True iOS background sessions
|
||||
- **Event-Driven**: No polling, immediate updates
|
||||
- **Lower Overhead**: Removed unused features
|
||||
- **Native Integration**: Tighter iOS system integration
|
||||
- **Cleaner Code**: Easier to maintain and extend
|
||||
|
||||
## Dependencies Changed
|
||||
|
||||
### Removed
|
||||
- `@kesha-antonov/react-native-background-downloader`
|
||||
|
||||
### Added
|
||||
- Custom `BackgroundDownloader` native module (local)
|
||||
|
||||
No external dependencies added, reducing maintenance burden.
|
||||
|
||||
## File Changes Summary
|
||||
|
||||
### New Files
|
||||
- `modules/background-downloader/` (entire module)
|
||||
- `providers/Downloads/MIGRATION.md`
|
||||
- `providers/Downloads/README.md`
|
||||
- `DOWNLOAD_SYSTEM_REFACTOR.md` (this file)
|
||||
|
||||
### Modified Files
|
||||
- `modules/index.ts` (exported new module)
|
||||
- `providers/DownloadProvider.tsx` (complete rewrite)
|
||||
|
||||
### Renamed Files
|
||||
- `providers/DownloadProvider.tsx` → `providers/DownloadProvider.deprecated.tsx`
|
||||
|
||||
### Unchanged
|
||||
- `providers/Downloads/types.ts` (types remain the same)
|
||||
- Database format and storage location
|
||||
- Public API for most common operations
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If issues arise:
|
||||
|
||||
1. Rename `DownloadProvider.deprecated.tsx` back to `DownloadProvider.tsx`
|
||||
2. Remove the `background-downloader` module export from `modules/index.ts`
|
||||
3. Re-install `@kesha-antonov/react-native-background-downloader`
|
||||
4. Rebuild the app
|
||||
|
||||
Note: The database format is unchanged, so existing downloads will work with either version.
|
||||
|
||||
## Success Metrics
|
||||
|
||||
The refactor is successful if:
|
||||
|
||||
- ✅ Downloads work in foreground
|
||||
- ✅ Downloads continue in background
|
||||
- ✅ Progress updates are accurate
|
||||
- ✅ Notifications work correctly
|
||||
- ✅ Files are saved and playable
|
||||
- ✅ No crashes or memory leaks
|
||||
- ✅ Performance is equal or better
|
||||
- ✅ Code is cleaner and more maintainable
|
||||
|
||||
## Conclusion
|
||||
|
||||
This refactor provides a solid foundation for the download system moving forward. The native module approach gives us full control over the download experience and makes it easier to add features in the future.
|
||||
|
||||
The simplified DownloadProvider focuses on core functionality while maintaining API compatibility, making this a low-risk, high-reward change.
|
||||
|
||||
Reference in New Issue
Block a user