refactor: remove deprecated download methods from PlatformBridge and MainActivity

This commit is contained in:
zarzet
2026-02-10 10:15:53 +07:00
parent d54b2249b6
commit c35a8dd803
3 changed files with 28 additions and 305 deletions
+28
View File
@@ -7,12 +7,40 @@
- "Use Primary Artist Only" setting: strips featured artists from folder names (e.g. "Justin Bieber, Quavo" becomes "Justin Bieber") for cleaner folder organization
- Supports separators: `, ` `;` `&` `feat.` `ft.` `featuring` `with` `x`
- Available in Settings > Download > below "Use Album Artist for folders"
- Unified download request contract (`DownloadRequestPayload`) for all providers/flows
- Includes full superset fields: lyrics mode, genre/label/copyright, provider IDs, SAF params, cover/quality settings
- Added strategy flags in payload: `use_extensions`, `use_fallback`
- New Go unified router entrypoint: `DownloadByStrategy(requestJSON)`
- Routing priority: YouTube service -> extension fallback -> built-in fallback -> direct service
- New Android method channel handler: `"downloadByStrategy"` -> `Gobackend.downloadByStrategy(...)`
### Changed
- Download queue execution now builds one payload and uses a single bridge entrypoint (`PlatformBridge.downloadByStrategy`) instead of branching into multiple bridge methods
- Dart `downloadByStrategy` now sends a single request to Go (`downloadByStrategy` channel); routing concern is centralized in Go backend
- Legacy Dart bridge methods (`downloadTrack`, `downloadWithFallback`, `downloadWithExtensions`, `downloadFromYouTube`) are now thin wrappers and marked `@Deprecated`
### Fixed
- Fixed lyrics mode "External .LRC" still embedding lyrics into metadata - `lyrics_mode` was not being sent to Go backend for single-service downloads and YouTube provider, causing Go to default to "embed"
- Fixed `flutter_local_notifications` v20 breaking changes - migrated all `initialize()`, `show()`, and `cancel()` calls from positional parameters to named parameters
- Fixed SAF duplicate folder bug: concurrent batch downloads creating empty folders with `(1)`, `(2)`, `(3)` suffixes - added synchronized lock to `ensureDocumentDir` in Kotlin with duplicate detection and cleanup
- Inconsistent parameter parity across download paths
- `downloadWithExtensions` now carries `copyright`
- YouTube path now carries `embed_max_quality_cover` and metadata parity fields
- Inconsistent success response metadata between direct/fallback flows
- Added shared Go response builder for `DownloadTrack` and `DownloadWithFallback`
- Success responses now consistently include `genre`, `label`, `copyright`, and `lyrics_lrc`
- YouTube success response now also includes extended metadata fields (`cover_url`, `genre`, `label`, `copyright`) for parity with other providers
### Technical
- Centralized request serialization in `PlatformBridge` via shared invoke helper and unified payload model
- Go strategy router normalizes incoming service casing before dispatch
- Verified integration after AAR refresh with:
- `flutter analyze`
- `go test -v ./...`
- Android Kotlin compile check (`:app:compileDebugKotlin`)
---
@@ -1294,24 +1294,6 @@ class MainActivity: FlutterFragmentActivity() {
}
result.success(response)
}
"downloadTrack" -> {
val requestJson = call.arguments as String
val response = withContext(Dispatchers.IO) {
handleSafDownload(requestJson) { json ->
Gobackend.downloadTrack(json)
}
}
result.success(response)
}
"downloadWithFallback" -> {
val requestJson = call.arguments as String
val response = withContext(Dispatchers.IO) {
handleSafDownload(requestJson) { json ->
Gobackend.downloadWithFallback(json)
}
}
result.success(response)
}
"downloadByStrategy" -> {
val requestJson = call.arguments as String
val response = withContext(Dispatchers.IO) {
@@ -2120,24 +2102,6 @@ class MainActivity: FlutterFragmentActivity() {
}
result.success(response)
}
"downloadWithExtensions" -> {
val requestJson = call.arguments as String
val response = withContext(Dispatchers.IO) {
handleSafDownload(requestJson) { json ->
Gobackend.downloadWithExtensionsJSON(json)
}
}
result.success(response)
}
"downloadFromYouTube" -> {
val requestJson = call.arguments as String
val response = withContext(Dispatchers.IO) {
handleSafDownload(requestJson) { json ->
Gobackend.downloadFromYouTube(json)
}
}
result.success(response)
}
"enrichTrackWithExtension" -> {
val extensionId = call.argument<String>("extension_id") ?: ""
val trackJson = call.argument<String>("track") ?: "{}"
-269
View File
@@ -103,137 +103,7 @@ class PlatformBridge {
return response;
}
@Deprecated('Use downloadByStrategy with DownloadRequestPayload.')
static Future<Map<String, dynamic>> downloadTrack({
required String isrc,
required String service,
required String spotifyId,
required String trackName,
required String artistName,
required String albumName,
String? albumArtist,
String? coverUrl,
required String outputDir,
required String filenameFormat,
String quality = 'LOSSLESS',
bool embedLyrics = true,
bool embedMaxQualityCover = true,
int trackNumber = 1,
int discNumber = 1,
int totalTracks = 1,
String? releaseDate,
String? itemId,
int durationMs = 0,
String? source,
String? genre,
String? label,
String? copyright,
String lyricsMode = 'embed',
String storageMode = 'app',
String safTreeUri = '',
String safRelativeDir = '',
String safFileName = '',
String safOutputExt = '',
}) async {
final payload = DownloadRequestPayload(
isrc: isrc,
service: service,
spotifyId: spotifyId,
trackName: trackName,
artistName: artistName,
albumName: albumName,
albumArtist: albumArtist ?? artistName,
coverUrl: coverUrl ?? '',
outputDir: outputDir,
filenameFormat: filenameFormat,
quality: quality,
embedLyrics: embedLyrics,
embedMaxQualityCover: embedMaxQualityCover,
trackNumber: trackNumber,
discNumber: discNumber,
totalTracks: totalTracks,
releaseDate: releaseDate ?? '',
itemId: itemId ?? '',
durationMs: durationMs,
source: source ?? '',
genre: genre ?? '',
label: label ?? '',
copyright: copyright ?? '',
lyricsMode: lyricsMode,
storageMode: storageMode,
safTreeUri: safTreeUri,
safRelativeDir: safRelativeDir,
safFileName: safFileName,
safOutputExt: safOutputExt,
);
return downloadByStrategy(payload: payload);
}
@Deprecated('Use downloadByStrategy with DownloadRequestPayload.')
static Future<Map<String, dynamic>> downloadWithFallback({
required String isrc,
required String spotifyId,
required String trackName,
required String artistName,
required String albumName,
String? albumArtist,
String? coverUrl,
required String outputDir,
required String filenameFormat,
String quality = 'LOSSLESS',
bool embedLyrics = true,
bool embedMaxQualityCover = true,
int trackNumber = 1,
int discNumber = 1,
int totalTracks = 1,
String? releaseDate,
String preferredService = 'tidal',
String? itemId,
int durationMs = 0,
String? genre,
String? label,
String? copyright,
String lyricsMode = 'embed',
String storageMode = 'app',
String safTreeUri = '',
String safRelativeDir = '',
String safFileName = '',
String safOutputExt = '',
}) async {
final payload = DownloadRequestPayload(
isrc: isrc,
service: preferredService,
spotifyId: spotifyId,
trackName: trackName,
artistName: artistName,
albumName: albumName,
albumArtist: albumArtist ?? artistName,
coverUrl: coverUrl ?? '',
outputDir: outputDir,
filenameFormat: filenameFormat,
quality: quality,
embedLyrics: embedLyrics,
embedMaxQualityCover: embedMaxQualityCover,
trackNumber: trackNumber,
discNumber: discNumber,
totalTracks: totalTracks,
releaseDate: releaseDate ?? '',
itemId: itemId ?? '',
durationMs: durationMs,
genre: genre ?? '',
label: label ?? '',
copyright: copyright ?? '',
lyricsMode: lyricsMode,
storageMode: storageMode,
safTreeUri: safTreeUri,
safRelativeDir: safRelativeDir,
safFileName: safFileName,
safOutputExt: safOutputExt,
);
return downloadByStrategy(payload: payload, useFallback: true);
}
static Future<Map<String, dynamic>> getDownloadProgress() async {
final result = await _channel.invokeMethod('getDownloadProgress');
@@ -849,78 +719,7 @@ class PlatformBridge {
return list.map((e) => e as Map<String, dynamic>).toList();
}
@Deprecated('Use downloadByStrategy with DownloadRequestPayload.')
static Future<Map<String, dynamic>> downloadWithExtensions({
required String isrc,
required String spotifyId,
required String trackName,
required String artistName,
required String albumName,
String? albumArtist,
String? coverUrl,
required String outputDir,
required String filenameFormat,
String quality = 'LOSSLESS',
bool embedLyrics = true,
bool embedMaxQualityCover = true,
int trackNumber = 1,
int discNumber = 1,
int totalTracks = 1,
String? releaseDate,
String? itemId,
int durationMs = 0,
String? source,
String? genre,
String? label,
String? copyright,
String? tidalId,
String? qobuzId,
String? deezerId,
String lyricsMode = 'embed',
String? preferredService,
String storageMode = 'app',
String safTreeUri = '',
String safRelativeDir = '',
String safFileName = '',
String safOutputExt = '',
}) async {
final payload = DownloadRequestPayload(
isrc: isrc,
service: preferredService ?? '',
spotifyId: spotifyId,
trackName: trackName,
artistName: artistName,
albumName: albumName,
albumArtist: albumArtist ?? artistName,
coverUrl: coverUrl ?? '',
outputDir: outputDir,
filenameFormat: filenameFormat,
quality: quality,
embedLyrics: embedLyrics,
embedMaxQualityCover: embedMaxQualityCover,
trackNumber: trackNumber,
discNumber: discNumber,
totalTracks: totalTracks,
releaseDate: releaseDate ?? '',
itemId: itemId ?? '',
durationMs: durationMs,
source: source ?? '',
genre: genre ?? '',
label: label ?? '',
copyright: copyright ?? '',
tidalId: tidalId ?? '',
qobuzId: qobuzId ?? '',
deezerId: deezerId ?? '',
lyricsMode: lyricsMode,
storageMode: storageMode,
safTreeUri: safTreeUri,
safRelativeDir: safRelativeDir,
safFileName: safFileName,
safOutputExt: safOutputExt,
);
return downloadByStrategy(payload: payload, useExtensions: true);
}
static Future<void> cleanupExtensions() async {
_log.d('cleanupExtensions');
@@ -1332,72 +1131,4 @@ class PlatformBridge {
// ==================== YOUTUBE / COBALT ====================
/// Download a track from YouTube using the Cobalt API.
/// YouTube is a lossy-only provider (Opus 256kbps or MP3 320kbps).
/// It does NOT participate in the lossless fallback chain.
@Deprecated('Use downloadByStrategy with DownloadRequestPayload.')
static Future<Map<String, dynamic>> downloadFromYouTube({
required String trackName,
required String artistName,
required String albumName,
String? albumArtist,
String? coverUrl,
required String outputDir,
required String filenameFormat,
String quality = 'opus_256',
int trackNumber = 1,
int discNumber = 1,
String? releaseDate,
String? itemId,
int durationMs = 0,
String? isrc,
String? spotifyId,
String? deezerId,
bool embedLyrics = true,
bool embedMaxQualityCover = true,
int totalTracks = 1,
String? genre,
String? label,
String? copyright,
String lyricsMode = 'embed',
String storageMode = 'app',
String safTreeUri = '',
String safRelativeDir = '',
String safFileName = '',
String safOutputExt = '',
}) async {
final payload = DownloadRequestPayload(
isrc: isrc ?? '',
service: 'youtube',
spotifyId: spotifyId ?? '',
trackName: trackName,
artistName: artistName,
albumName: albumName,
albumArtist: albumArtist ?? artistName,
coverUrl: coverUrl ?? '',
outputDir: outputDir,
filenameFormat: filenameFormat,
quality: quality,
embedLyrics: embedLyrics,
embedMaxQualityCover: embedMaxQualityCover,
trackNumber: trackNumber,
discNumber: discNumber,
totalTracks: totalTracks,
releaseDate: releaseDate ?? '',
itemId: itemId ?? '',
durationMs: durationMs,
deezerId: deezerId ?? '',
genre: genre ?? '',
label: label ?? '',
copyright: copyright ?? '',
lyricsMode: lyricsMode,
storageMode: storageMode,
safTreeUri: safTreeUri,
safRelativeDir: safRelativeDir,
safFileName: safFileName,
safOutputExt: safOutputExt,
);
return downloadByStrategy(payload: payload);
}
}