From 901fa34d80587ffa8a17b39d757882b4ec5f1b89 Mon Sep 17 00:00:00 2001 From: zarzet Date: Sun, 26 Jul 2026 18:32:40 +0700 Subject: [PATCH] refactor(bridge): remove dead cross-layer platform bridge methods --- .../kotlin/com/zarz/spotiflac/MainActivity.kt | 151 +----------------- go_backend/deezer.go | 61 ------- go_backend/deezer_supplement_test.go | 11 -- go_backend/exports.go | 21 ++- go_backend/exports_deezer.go | 16 -- go_backend/exports_download.go | 10 -- go_backend/exports_extensions.go | 92 ----------- go_backend/exports_lyrics.go | 19 --- ...exports_songlink_lyrics_supplement_test.go | 16 +- go_backend/exports_supplement_test.go | 27 +--- .../extension_provider_supplement_test.go | 4 +- go_backend/extension_provider_wrapper.go | 34 ++-- go_backend/extension_providers.go | 101 +----------- go_backend/progress.go | 19 --- ios/Runner/AppDelegate.swift | 82 +--------- lib/services/platform_bridge.dart | 115 ++----------- 16 files changed, 63 insertions(+), 716 deletions(-) diff --git a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt index af79e6dc..17af12fb 100644 --- a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt +++ b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt @@ -1826,66 +1826,6 @@ class MainActivity: FlutterFragmentActivity() { return result.toString() } - private fun runPostProcessingSaf(fileUriStr: String, metadataJson: String): String { - val uri = Uri.parse(fileUriStr) - val doc = DocumentFile.fromSingleUri(this, uri) - ?: return errorJson("SAF file not found") - - val tempInput = copyUriToTemp(uri) ?: return errorJson("Failed to copy SAF file to temp") - val tempDir = File(tempInput).parentFile?.absolutePath ?: "" - if (tempDir.isNotBlank()) { - try { - Gobackend.allowDownloadDir(tempDir) - } catch (_: Exception) {} - } - - val response = Gobackend.runPostProcessingJSON(tempInput, metadataJson) - val respObj = JSONObject(response) - if (!respObj.optBoolean("success", false)) { - try { - File(tempInput).delete() - } catch (_: Exception) {} - return response - } - - val newPath = respObj.optString("new_file_path", "") - val outputPath = if (newPath.isNotBlank()) newPath else tempInput - val outputFile = File(outputPath) - if (!outputFile.exists()) { - try { - File(tempInput).delete() - } catch (_: Exception) {} - respObj.put("success", false) - respObj.put("error", "postProcess output not found") - return respObj.toString() - } - - val newName = outputFile.name - if (!newName.isNullOrBlank() && doc.name != null && doc.name != newName) { - try { - doc.renameTo(newName) - } catch (_: Exception) {} - } - - val writeOk = writeUriFromPath(uri, outputFile.absolutePath) - if (!writeOk) { - respObj.put("success", false) - respObj.put("error", "failed to write postProcess output to SAF") - return respObj.toString() - } - - try { - if (outputPath != tempInput) { - outputFile.delete() - } - File(tempInput).delete() - } catch (_: Exception) {} - - respObj.put("new_file_path", uri.toString()) - respObj.put("file_path", uri.toString()) - return respObj.toString() - } - private fun runPostProcessingSafV2(fileUriStr: String, metadataJson: String): String { val uri = Uri.parse(fileUriStr) val doc = DocumentFile.fromSingleUri(this, uri) @@ -2255,32 +2195,12 @@ class MainActivity: FlutterFragmentActivity() { } result.success(response) } - "getDownloadProgress" -> { - val response = withContext(Dispatchers.IO) { - Gobackend.getDownloadProgress() - } - result.success(parseJsonPayload(response)) - } "getAllDownloadProgress" -> { val response = withContext(Dispatchers.IO) { Gobackend.getAllDownloadProgress() } result.success(parseJsonPayload(response)) } - "initItemProgress" -> { - val itemId = call.argument("item_id") ?: "" - withContext(Dispatchers.IO) { - Gobackend.initItemProgress(itemId) - } - result.success(null) - } - "finishItemProgress" -> { - val itemId = call.argument("item_id") ?: "" - withContext(Dispatchers.IO) { - Gobackend.finishItemProgress(itemId) - } - result.success(null) - } "clearItemProgress" -> { val itemId = call.argument("item_id") ?: "" withContext(Dispatchers.IO) { @@ -2324,14 +2244,6 @@ class MainActivity: FlutterFragmentActivity() { } result.success(null) } - "checkDuplicate" -> { - val outputDir = call.argument("output_dir") ?: "" - val isrc = call.argument("isrc") ?: "" - val response = withContext(Dispatchers.IO) { - Gobackend.checkDuplicate(outputDir, isrc) - } - result.success(response) - } "checkDuplicatesBatch" -> { val outputDir = call.argument("output_dir") ?: "" val tracksJson = call.argument("tracks") ?: "[]" @@ -2588,16 +2500,6 @@ class MainActivity: FlutterFragmentActivity() { result.error("share_failed", e.message, null) } } - "fetchLyrics" -> { - val spotifyId = call.argument("spotify_id") ?: "" - val trackName = call.argument("track_name") ?: "" - val artistName = call.argument("artist_name") ?: "" - val durationMs = call.argument("duration_ms")?.toLong() ?: 0L - val response = withContext(Dispatchers.IO) { - Gobackend.fetchLyrics(spotifyId, trackName, artistName, durationMs) - } - result.success(response) - } "getLyricsLRC" -> { val spotifyId = call.argument("spotify_id") ?: "" val trackName = call.argument("track_name") ?: "" @@ -3116,14 +3018,6 @@ class MainActivity: FlutterFragmentActivity() { } result.success(null) } - "getDeezerRelatedArtists" -> { - val artistId = call.argument("artist_id") ?: "" - val limit = call.argument("limit") ?: 12 - val response = withContext(Dispatchers.IO) { - Gobackend.getDeezerRelatedArtists(artistId, limit.toLong()) - } - result.success(response) - } "getProviderMetadata" -> { val providerId = call.argument("provider_id") ?: "" val resourceType = call.argument("resource_type") ?: "" @@ -3354,14 +3248,6 @@ class MainActivity: FlutterFragmentActivity() { } result.success(response) } - "searchTracksWithExtensions" -> { - val query = call.argument("query") ?: "" - val limit = call.argument("limit") ?: 20 - val response = withContext(Dispatchers.IO) { - Gobackend.searchTracksWithExtensionsJSON(query, limit.toLong()) - } - result.success(response) - } "searchTracksWithMetadataProviders" -> { val query = call.argument("query") ?: "" val limit = call.argument("limit") ?: 20 @@ -3499,12 +3385,6 @@ class MainActivity: FlutterFragmentActivity() { } result.success(null) } - "getSearchProviders" -> { - val response = withContext(Dispatchers.IO) { - Gobackend.getSearchProvidersJSON() - } - result.success(response) - } "handleURLWithExtension" -> { val url = call.argument("url") ?: "" val response = withContext(Dispatchers.IO) { @@ -3519,21 +3399,11 @@ class MainActivity: FlutterFragmentActivity() { } result.success(response) } - "getURLHandlers" -> { + "getTrackPlatformLinks" -> { + val spotifyId = call.argument("spotify_id") ?: "" + val isrc = call.argument("isrc") ?: "" val response = withContext(Dispatchers.IO) { - Gobackend.getURLHandlersJSON() - } - result.success(response) - } - "runPostProcessing" -> { - val filePath = call.argument("file_path") ?: "" - val metadataJson = call.argument("metadata") ?: "" - val response = withContext(Dispatchers.IO) { - if (filePath.startsWith("content://")) { - runPostProcessingSaf(filePath, metadataJson) - } else { - Gobackend.runPostProcessingJSON(filePath, metadataJson) - } + Gobackend.getTrackPlatformLinksJSON(spotifyId, isrc) } result.success(response) } @@ -3562,12 +3432,6 @@ class MainActivity: FlutterFragmentActivity() { } result.success(response) } - "getPostProcessingProviders" -> { - val response = withContext(Dispatchers.IO) { - Gobackend.getPostProcessingProvidersJSON() - } - result.success(response) - } "initExtensionRepo" -> { val cacheDir = call.argument("cache_dir") ?: "" withContext(Dispatchers.IO) { @@ -3637,13 +3501,6 @@ class MainActivity: FlutterFragmentActivity() { } result.success(response) } - "getExtensionBrowseCategories" -> { - val extensionId = call.argument("extension_id") ?: "" - val response = withContext(Dispatchers.IO) { - Gobackend.getExtensionBrowseCategoriesJSON(extensionId) - } - result.success(response) - } "setLibraryCoverCacheDir" -> { val cacheDir = call.argument("cache_dir") ?: "" withContext(Dispatchers.IO) { diff --git a/go_backend/deezer.go b/go_backend/deezer.go index 55742ea3..94f4566a 100644 --- a/go_backend/deezer.go +++ b/go_backend/deezer.go @@ -19,7 +19,6 @@ const ( deezerTrackURL = deezerBaseURL + "/track/%s" deezerAlbumURL = deezerBaseURL + "/album/%s" deezerArtistURL = deezerBaseURL + "/artist/%s" - deezerArtistRelatedURL = deezerBaseURL + "/artist/%s/related" deezerPlaylistURL = deezerBaseURL + "/playlist/%s" deezerCacheTTL = 10 * time.Minute @@ -846,66 +845,6 @@ func (c *DeezerClient) fetchAlbumTrackCounts(ctx context.Context, albums []Artis wg.Wait() } -func (c *DeezerClient) GetRelatedArtists(ctx context.Context, artistID string, limit int) ([]SearchArtistResult, error) { - normalizedArtistID := strings.TrimSpace(strings.TrimPrefix(artistID, "deezer:")) - if normalizedArtistID == "" { - return nil, fmt.Errorf("invalid Deezer artist ID") - } - - effectiveLimit := limit - if effectiveLimit <= 0 { - effectiveLimit = 12 - } - - relatedURL := fmt.Sprintf("%s?limit=%d", fmt.Sprintf(deezerArtistRelatedURL, normalizedArtistID), effectiveLimit) - var relatedResp struct { - Data []struct { - ID int64 `json:"id"` - Name string `json:"name"` - Picture string `json:"picture"` - PictureMedium string `json:"picture_medium"` - PictureBig string `json:"picture_big"` - PictureXL string `json:"picture_xl"` - NbFan int `json:"nb_fan"` - } `json:"data"` - Error *struct { - Type string `json:"type"` - Message string `json:"message"` - Code int `json:"code"` - } `json:"error,omitempty"` - } - - if err := c.getJSON(ctx, relatedURL, &relatedResp); err != nil { - return nil, err - } - if relatedResp.Error != nil { - return nil, fmt.Errorf("deezer related artists error: %s", relatedResp.Error.Message) - } - - result := make([]SearchArtistResult, 0, len(relatedResp.Data)) - for _, artist := range relatedResp.Data { - imageURL := artist.PictureXL - if imageURL == "" { - imageURL = artist.PictureBig - } - if imageURL == "" { - imageURL = artist.PictureMedium - } - if imageURL == "" { - imageURL = artist.Picture - } - - result = append(result, SearchArtistResult{ - ID: fmt.Sprintf("deezer:%d", artist.ID), - Name: artist.Name, - Images: imageURL, - Followers: artist.NbFan, - Popularity: 0, - }) - } - return result, nil -} - func (c *DeezerClient) GetPlaylist(ctx context.Context, playlistID string) (*PlaylistResponsePayload, error) { playlistURL := fmt.Sprintf(deezerPlaylistURL, playlistID) diff --git a/go_backend/deezer_supplement_test.go b/go_backend/deezer_supplement_test.go index 6cef61d8..02a907a8 100644 --- a/go_backend/deezer_supplement_test.go +++ b/go_backend/deezer_supplement_test.go @@ -78,17 +78,6 @@ func TestDeezerClientWithFakeHTTP(t *testing.T) { t.Fatalf("cached artist = %#v/%v", cachedArtist, err) } - related, err := client.GetRelatedArtists(ctx, "deezer:301", 3) - if err != nil { - t.Fatalf("GetRelatedArtists: %v", err) - } - if len(related) != 1 || related[0].ID != "deezer:302" { - t.Fatalf("related = %#v", related) - } - if _, err := client.GetRelatedArtists(ctx, "", 0); err == nil { - t.Fatal("expected invalid related artist ID") - } - playlist, err := client.GetPlaylist(ctx, "401") if err != nil { t.Fatalf("GetPlaylist: %v", err) diff --git a/go_backend/exports.go b/go_backend/exports.go index 3cc6e767..e589df80 100644 --- a/go_backend/exports.go +++ b/go_backend/exports.go @@ -63,6 +63,16 @@ func SetSongLinkNetworkOptions(allowHTTP, insecureTLS bool) { SetNetworkCompatibilityOptions(allowHTTP, insecureTLS) } +// GetTrackPlatformLinksJSON returns {"platforms": {platformID: url}} for a +// track, resolved via song.link (memory-cached; either ID may be empty). +func GetTrackPlatformLinksJSON(spotifyTrackID string, isrc string) (string, error) { + links, err := NewSongLinkClient().GetTrackPlatformLinks(spotifyTrackID, isrc) + if err != nil { + return "", err + } + return marshalJSONString(map[string]any{"platforms": links}) +} + func SetDownloadDirectory(path string) error { return setDownloadDir(path) } @@ -74,17 +84,6 @@ func AllowDownloadDir(path string) { AddAllowedDownloadDir(path) } -func CheckDuplicate(outputDir, isrc string) (string, error) { - existingFile, exists := CheckISRCExists(outputDir, isrc) - - result := map[string]any{ - "exists": exists, - "filepath": existingFile, - } - - return marshalJSONString(result) -} - func CheckDuplicatesBatch(outputDir, tracksJSON string) (string, error) { return CheckFilesExistParallel(outputDir, tracksJSON) } diff --git a/go_backend/exports_deezer.go b/go_backend/exports_deezer.go index 2b4443c4..c335149d 100644 --- a/go_backend/exports_deezer.go +++ b/go_backend/exports_deezer.go @@ -17,22 +17,6 @@ func GetTrackCacheSize() int { func ClearTrackIDCache() { } -func GetDeezerRelatedArtists(artistID string, limit int) (string, error) { - ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) - defer cancel() - - client := GetDeezerClient() - artists, err := client.GetRelatedArtists(ctx, artistID, limit) - if err != nil { - return "", err - } - - resp := map[string]any{ - "artists": artists, - } - return marshalJSONString(resp) -} - func GetDeezerMetadata(resourceType, resourceID string) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() diff --git a/go_backend/exports_download.go b/go_backend/exports_download.go index cd4e6dbe..e782209d 100644 --- a/go_backend/exports_download.go +++ b/go_backend/exports_download.go @@ -383,12 +383,6 @@ func DownloadByStrategy(requestJSON string) (string, error) { return errorResponse("Extension providers are disabled; built-in download providers have been retired") } -func GetDownloadProgress() string { - progress := getProgress() - jsonBytes, _ := json.Marshal(progress) - return string(jsonBytes) -} - func GetAllDownloadProgress() string { return GetMultiProgress() } @@ -401,10 +395,6 @@ func InitItemProgress(itemID string) { StartItemProgress(itemID) } -func FinishItemProgress(itemID string) { - CompleteItemProgress(itemID) -} - func ClearItemProgress(itemID string) { RemoveItemProgress(itemID) } diff --git a/go_backend/exports_extensions.go b/go_backend/exports_extensions.go index 4ace8f71..781b0f10 100644 --- a/go_backend/exports_extensions.go +++ b/go_backend/exports_extensions.go @@ -432,16 +432,6 @@ func SetExtensionSettingsJSON(extensionID, settingsJSON string) error { return manager.InitializeExtension(extensionID, settings) } -func SearchTracksWithExtensionsJSON(query string, limit int) (string, error) { - manager := getExtensionManager() - tracks, err := manager.SearchTracksWithExtensions(query, limit) - if err != nil { - return "", err - } - - return marshalJSONString(tracks) -} - func SearchTracksWithMetadataProvidersJSON(query string, limit int, includeExtensions bool) (string, error) { manager := getExtensionManager() tracks, err := manager.SearchTracksWithMetadataProviders(query, limit, includeExtensions) @@ -821,24 +811,6 @@ func CustomSearchWithExtensionJSONWithRequestID(extensionID, query string, optio return marshalJSONString(result) } -func GetSearchProvidersJSON() (string, error) { - manager := getExtensionManager() - providers := manager.GetSearchProviders() - - result := make([]map[string]any, 0, len(providers)) - for _, p := range providers { - result = append(result, map[string]any{ - "id": p.extension.ID, - "display_name": p.extension.Manifest.DisplayName, - "placeholder": p.extension.Manifest.SearchBehavior.Placeholder, - "primary": p.extension.Manifest.SearchBehavior.Primary, - "icon": p.extension.Manifest.SearchBehavior.Icon, - }) - } - - return marshalJSONString(result) -} - func HandleURLWithExtensionJSON(url string) (string, error) { manager := getExtensionManager() resultWithID, err := manager.HandleURLWithExtension(url) @@ -1025,39 +997,6 @@ func FindURLHandlerJSON(url string) string { return handler.extension.ID } -func GetURLHandlersJSON() (string, error) { - manager := getExtensionManager() - handlers := manager.GetURLHandlers() - - result := make([]map[string]any, 0, len(handlers)) - for _, h := range handlers { - result = append(result, map[string]any{ - "id": h.extension.ID, - "display_name": h.extension.Manifest.DisplayName, - "patterns": h.extension.Manifest.URLHandler.Patterns, - }) - } - - return marshalJSONString(result) -} - -func RunPostProcessingJSON(filePath, metadataJSON string) (string, error) { - var metadata map[string]any - if metadataJSON != "" { - if err := json.Unmarshal([]byte(metadataJSON), &metadata); err != nil { - metadata = make(map[string]any) - } - } - - manager := getExtensionManager() - result, err := manager.RunPostProcessing(filePath, metadata) - if err != nil { - return "", err - } - - return marshalJSONString(result) -} - func RunPostProcessingV2JSON(inputJSON, metadataJSON string) (string, error) { var metadata map[string]any if metadataJSON != "" { @@ -1082,33 +1021,6 @@ func RunPostProcessingV2JSON(inputJSON, metadataJSON string) (string, error) { return marshalJSONString(result) } -func GetPostProcessingProvidersJSON() (string, error) { - manager := getExtensionManager() - providers := manager.GetPostProcessingProviders() - - result := make([]map[string]any, 0, len(providers)) - for _, p := range providers { - hooks := make([]map[string]any, 0) - for _, h := range p.extension.Manifest.GetPostProcessingHooks() { - hooks = append(hooks, map[string]any{ - "id": h.ID, - "name": h.Name, - "description": h.Description, - "default_enabled": h.DefaultEnabled, - "supported_formats": h.SupportedFormats, - }) - } - - result = append(result, map[string]any{ - "id": p.extension.ID, - "display_name": p.extension.Manifest.DisplayName, - "hooks": hooks, - }) - } - - return marshalJSONString(result) -} - func callExtensionFunctionJSON(extensionID, functionName string, timeout time.Duration) (string, error) { return callExtensionFunctionJSONWithRequestID(extensionID, functionName, timeout, "") } @@ -1187,10 +1099,6 @@ func GetExtensionHomeFeedJSONWithRequestID(extensionID, requestID string) (strin return callExtensionFunctionJSONWithRequestID(extensionID, "getHomeFeed", 60*time.Second, requestID) } -func GetExtensionBrowseCategoriesJSON(extensionID string) (string, error) { - return callExtensionFunctionJSON(extensionID, "getBrowseCategories", 30*time.Second) -} - func CancelExtensionRequestJSON(requestID string) { cancelExtensionRequest(requestID) } diff --git a/go_backend/exports_lyrics.go b/go_backend/exports_lyrics.go index b376cbcc..989ede5c 100644 --- a/go_backend/exports_lyrics.go +++ b/go_backend/exports_lyrics.go @@ -7,25 +7,6 @@ import ( "strings" ) -func FetchLyrics(spotifyID, trackName, artistName string, durationMs int64) (string, error) { - client := NewLyricsClient() - durationSec := float64(durationMs) / 1000.0 - lyrics, err := client.FetchLyricsAllSources(spotifyID, trackName, artistName, durationSec) - if err != nil { - return "", err - } - - result := map[string]any{ - "success": true, - "source": lyrics.Source, - "sync_type": lyrics.SyncType, - "lines": lyrics.Lines, - "instrumental": lyrics.Instrumental, - } - - return marshalJSONString(result) -} - func GetLyricsLRC(spotifyID, trackName, artistName string, filePath string, durationMs int64) (string, error) { if filePath != "" { lyrics, err := ExtractLyrics(filePath) diff --git a/go_backend/exports_songlink_lyrics_supplement_test.go b/go_backend/exports_songlink_lyrics_supplement_test.go index be0abe81..4c6d751c 100644 --- a/go_backend/exports_songlink_lyrics_supplement_test.go +++ b/go_backend/exports_songlink_lyrics_supplement_test.go @@ -20,9 +20,6 @@ func TestLyricsExportWrappersWithoutNetwork(t *testing.T) { t.Fatal(err) } - if jsonText, err := FetchLyrics("spotify-1", "Song Instrumental", "Artist", 180000); err != nil || !strings.Contains(jsonText, `"instrumental":true`) { - t.Fatalf("FetchLyrics instrumental = %q/%v", jsonText, err) - } if lrc, err := GetLyricsLRC("spotify-1", "Song Instrumental", "Artist", "", 180000); err != nil || lrc != "[instrumental:true]" { t.Fatalf("GetLyricsLRC instrumental = %q/%v", lrc, err) } @@ -112,6 +109,19 @@ func TestSongLinkExportWrappersWithFakeClient(t *testing.T) { t.Fatal("songLinkExtractDeezerTrackID mismatch") } + if linksJSON, err := GetTrackPlatformLinksJSON("spotify-1", ""); err != nil || + !strings.Contains(linksJSON, `"tidal":"https://listen.tidal.com/track/202"`) || + !strings.Contains(linksJSON, `"spotify":`) { + t.Fatalf("GetTrackPlatformLinksJSON = %q/%v", linksJSON, err) + } + // Second call must come from the links cache, not a new request. + if cached, hit, cachedErr := trackPlatformLinksCacheLookup(GetSongLinkRegion() + "|spotify:spotify-1"); !hit || cachedErr || cached["tidal"] == "" { + t.Fatalf("trackPlatformLinksCacheLookup = %#v hit=%v err=%v", cached, hit, cachedErr) + } + if _, err := GetTrackPlatformLinksJSON("", ""); err == nil { + t.Fatal("GetTrackPlatformLinksJSON with empty IDs should error") + } + deezerClient = &DeezerClient{ httpClient: &http.Client{Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) { body := fakeDeezerResponse(req.URL.Path, req.URL.RawQuery) diff --git a/go_backend/exports_supplement_test.go b/go_backend/exports_supplement_test.go index 0523bd3e..ecb88fc6 100644 --- a/go_backend/exports_supplement_test.go +++ b/go_backend/exports_supplement_test.go @@ -134,10 +134,9 @@ func TestExportsJSONWrappersAndExtensionManagerSurface(t *testing.T) { } InitItemProgress("item-1") - FinishItemProgress("item-1") ClearItemProgress("item-1") CancelDownload("item-1") - if GetDownloadProgress() == "" || GetAllDownloadProgress() == "" || GetAllDownloadProgressDelta(0) == "" { + if GetAllDownloadProgress() == "" || GetAllDownloadProgressDelta(0) == "" { t.Fatal("expected progress JSON") } CleanupConnections() @@ -194,9 +193,6 @@ func TestExportsJSONWrappersAndExtensionManagerSurface(t *testing.T) { if err := SetDownloadDirectory(dir); err != nil { t.Fatalf("SetDownloadDirectory: %v", err) } - if duplicateJSON, err := CheckDuplicate(dir, ""); err != nil || !strings.Contains(duplicateJSON, "exists") { - t.Fatalf("CheckDuplicate = %q/%v", duplicateJSON, err) - } if batchJSON, err := CheckDuplicatesBatch(dir, `[{"isrc":"","track_name":"Song","artist_name":"Artist"}]`); err != nil || !strings.Contains(batchJSON, "Song") { t.Fatalf("CheckDuplicatesBatch = %q/%v", batchJSON, err) } @@ -262,9 +258,6 @@ func TestExportsJSONWrappersAndExtensionManagerSurface(t *testing.T) { t.Fatal("expected settings JSON error") } - if jsonText, err := SearchTracksWithExtensionsJSON("song", 5); err != nil || !strings.Contains(jsonText, "search-1") { - t.Fatalf("SearchTracksWithExtensionsJSON = %q/%v", jsonText, err) - } if jsonText, err := SearchTracksWithMetadataProvidersJSON("song", 5, true); err != nil || !strings.Contains(jsonText, "search-1") { t.Fatalf("SearchTracksWithMetadataProvidersJSON = %q/%v", jsonText, err) } @@ -362,9 +355,6 @@ func TestExportsJSONWrappersAndExtensionManagerSurface(t *testing.T) { if _, err := GetDeezerMetadata("bad", "1"); err == nil { t.Fatal("expected unsupported Deezer metadata type") } - if jsonText, err := GetDeezerRelatedArtists("301", 2); err != nil || !strings.Contains(jsonText, "Related") { - t.Fatalf("GetDeezerRelatedArtists = %q/%v", jsonText, err) - } if jsonText, err := GetDeezerExtendedMetadata("101"); err != nil || !strings.Contains(jsonText, "Label") { t.Fatalf("GetDeezerExtendedMetadata = %q/%v", jsonText, err) } @@ -385,37 +375,22 @@ func TestExportsJSONWrappersAndExtensionManagerSurface(t *testing.T) { if customJSON, err := CustomSearchWithExtensionJSONWithRequestID(ext.ID, "needle", `not-json`, "req-custom"); err != nil || !strings.Contains(customJSON, "custom-1") { t.Fatalf("CustomSearchWithExtensionJSONWithRequestID = %q/%v", customJSON, err) } - if providersJSON, err := GetSearchProvidersJSON(); err != nil || !strings.Contains(providersJSON, "coverage-ext") { - t.Fatalf("GetSearchProvidersJSON = %q/%v", providersJSON, err) - } if found := FindURLHandlerJSON("https://example.test/track/1"); found != ext.ID { t.Fatalf("FindURLHandlerJSON = %q", found) } - if handlersJSON, err := GetURLHandlersJSON(); err != nil || !strings.Contains(handlersJSON, "coverage-ext") { - t.Fatalf("GetURLHandlersJSON = %q/%v", handlersJSON, err) - } if handledJSON, err := HandleURLWithExtensionJSON("https://example.test/track/1"); err != nil || !strings.Contains(handledJSON, "url-track") { t.Fatalf("HandleURLWithExtensionJSON = %q/%v", handledJSON, err) } - if postJSON, err := RunPostProcessingJSON(filepath.Join(dir, "song.flac"), `{"title":"Song"}`); err != nil || !strings.Contains(postJSON, "success") { - t.Fatalf("RunPostProcessingJSON = %q/%v", postJSON, err) - } v2Input := `{"path":"` + escapeJSONPath(filepath.Join(dir, "song.flac")) + `","uri":"content://song","name":"song.flac","mime_type":"audio/flac","size":10}` if postJSON, err := RunPostProcessingV2JSON(v2Input, `not-json`); err != nil || !strings.Contains(postJSON, "success") { t.Fatalf("RunPostProcessingV2JSON = %q/%v", postJSON, err) } - if postProviders, err := GetPostProcessingProvidersJSON(); err != nil || !strings.Contains(postProviders, "hook") { - t.Fatalf("GetPostProcessingProvidersJSON = %q/%v", postProviders, err) - } if feedJSON, err := GetExtensionHomeFeedJSON(ext.ID); err != nil || !strings.Contains(feedJSON, "home-1") { t.Fatalf("GetExtensionHomeFeedJSON = %q/%v", feedJSON, err) } if feedJSON, err := GetExtensionHomeFeedJSONWithRequestID(ext.ID, "req-home"); err != nil || !strings.Contains(feedJSON, "home-1") { t.Fatalf("GetExtensionHomeFeedJSONWithRequestID = %q/%v", feedJSON, err) } - if categoriesJSON, err := GetExtensionBrowseCategoriesJSON(ext.ID); err != nil || !strings.Contains(categoriesJSON, "cat-1") { - t.Fatalf("GetExtensionBrowseCategoriesJSON = %q/%v", categoriesJSON, err) - } CancelExtensionRequestJSON("req-home") storeDir := filepath.Join(dir, "store") diff --git a/go_backend/extension_provider_supplement_test.go b/go_backend/extension_provider_supplement_test.go index c1fe515b..1ef11ae9 100644 --- a/go_backend/extension_provider_supplement_test.go +++ b/go_backend/extension_provider_supplement_test.go @@ -92,9 +92,9 @@ func TestExtensionProviderWrapperFullSurface(t *testing.T) { t.Fatalf("url result = %#v", urlResult) } - post, err := provider.PostProcess(filepath.Join(t.TempDir(), "song.flac"), map[string]any{"title": "Song"}, "hook") + post, err := provider.PostProcessV2(PostProcessInput{Path: filepath.Join(t.TempDir(), "song.flac")}, map[string]any{"title": "Song"}, "hook") if err != nil { - t.Fatalf("PostProcess: %v", err) + t.Fatalf("PostProcessV2: %v", err) } if !post.Success || post.BitDepth != 24 || post.SampleRate != 96000 { t.Fatalf("post = %#v", post) diff --git a/go_backend/extension_provider_wrapper.go b/go_backend/extension_provider_wrapper.go index 3e7be823..73fbeabe 100644 --- a/go_backend/extension_provider_wrapper.go +++ b/go_backend/extension_provider_wrapper.go @@ -847,11 +847,9 @@ func postProcessInputMap(input PostProcessInput) map[string]any { const PostProcessTimeout = 2 * time.Minute -// postProcessCommon backs both PostProcess (V1) and PostProcessV2. V1 probes -// only extension.postProcess (its original contract: V2-only extensions are -// not invoked via V1); V2 probes postProcessV2 first, then falls back to -// postProcess. -func (p *extensionProviderWrapper) postProcessCommon(input PostProcessInput, metadata map[string]any, hookID string, preferV2 bool) (*PostProcessResult, error) { +// PostProcessV2 probes extension.postProcessV2 first, then falls back to the +// legacy extension.postProcess contract. +func (p *extensionProviderWrapper) PostProcessV2(input PostProcessInput, metadata map[string]any, hookID string) (*PostProcessResult, error) { if !p.extension.Manifest.HasPostProcessing() { return nil, fmt.Errorf("extension '%s' does not support post-processing", p.extension.ID) } @@ -861,19 +859,13 @@ func (p *extensionProviderWrapper) postProcessCommon(input PostProcessInput, met filePath := input.Path - perfName := "postProcess" - var invoke func(*goja.Runtime) (goja.Value, error) - if preferV2 { - perfName = "postProcessV2" - inputMap := postProcessInputMap(input) - invoke = func(vm *goja.Runtime) (goja.Value, error) { - if hasExtensionMethod(vm, "postProcessV2") { - return invokeExtensionMethod(vm, "postProcessV2", inputMap, metadata, hookID) - } - return invokeExtensionMethod(vm, "postProcess", filePath, metadata, hookID) + perfName := "postProcessV2" + inputMap := postProcessInputMap(input) + invoke := func(vm *goja.Runtime) (goja.Value, error) { + if hasExtensionMethod(vm, "postProcessV2") { + return invokeExtensionMethod(vm, "postProcessV2", inputMap, metadata, hookID) } - } else { - invoke = extensionMethodInvocation("postProcess", filePath, metadata, hookID) + return invokeExtensionMethod(vm, "postProcess", filePath, metadata, hookID) } result, err := callExtension(p, extCallOpts{ @@ -898,14 +890,6 @@ func (p *extensionProviderWrapper) postProcessCommon(input PostProcessInput, met return result, nil } -func (p *extensionProviderWrapper) PostProcess(filePath string, metadata map[string]any, hookID string) (*PostProcessResult, error) { - return p.postProcessCommon(PostProcessInput{Path: filePath}, metadata, hookID, false) -} - -func (p *extensionProviderWrapper) PostProcessV2(input PostProcessInput, metadata map[string]any, hookID string) (*PostProcessResult, error) { - return p.postProcessCommon(input, metadata, hookID, true) -} - type ExtLyricsResult struct { Lines []ExtLyricsLine `json:"lines"` SyncType string `json:"syncType"` diff --git a/go_backend/extension_providers.go b/go_backend/extension_providers.go index b41fd94d..f6fe0c9f 100644 --- a/go_backend/extension_providers.go +++ b/go_backend/extension_providers.go @@ -34,49 +34,6 @@ func (m *extensionManager) GetDownloadProviders() []*extensionProviderWrapper { return providers } -func (m *extensionManager) SearchTracksWithExtensions(query string, limit int) ([]ExtTrackMetadata, error) { - providers := m.GetMetadataProviders() - if len(providers) == 0 { - return nil, nil - } - - providerByID := make(map[string]*extensionProviderWrapper, len(providers)) - orderedProviders := make([]*extensionProviderWrapper, 0, len(providers)) - for _, provider := range providers { - providerByID[provider.extension.ID] = provider - } - for _, providerID := range GetMetadataProviderPriority() { - if provider := providerByID[providerID]; provider != nil { - orderedProviders = append(orderedProviders, provider) - delete(providerByID, providerID) - } - } - if len(providerByID) > 0 { - remainingIDs := make([]string, 0, len(providerByID)) - for providerID := range providerByID { - remainingIDs = append(remainingIDs, providerID) - } - sort.Strings(remainingIDs) - for _, providerID := range remainingIDs { - orderedProviders = append(orderedProviders, providerByID[providerID]) - } - } - - var allTracks []ExtTrackMetadata - for _, provider := range orderedProviders { - result, err := provider.SearchTracks(query, limit) - if err != nil { - GoLog("[Extension] Search error from %s: %v\n", provider.extension.ID, err) - continue - } - if result != nil { - allTracks = append(allTracks, result.Tracks...) - } - } - - return allTracks, nil -} - func metadataTrackDedupKey(track ExtTrackMetadata) string { if isrc := strings.TrimSpace(track.ISRC); isrc != "" { return "isrc:" + strings.ToUpper(isrc) @@ -176,32 +133,6 @@ func (m *extensionManager) SearchTracksWithMetadataProvidersForItemID(query stri return tracks, nil } -func (m *extensionManager) GetSearchProviders() []*extensionProviderWrapper { - m.mu.RLock() - defer m.mu.RUnlock() - - var providers []*extensionProviderWrapper - for _, ext := range m.extensions { - if ext.Enabled && ext.Manifest.HasCustomSearch() && ext.Error == "" { - providers = append(providers, newExtensionProviderWrapper(ext)) - } - } - return providers -} - -func (m *extensionManager) GetURLHandlers() []*extensionProviderWrapper { - m.mu.RLock() - defer m.mu.RUnlock() - - var providers []*extensionProviderWrapper - for _, ext := range m.extensions { - if ext.Enabled && ext.Manifest.HasURLHandler() && ext.Error == "" { - providers = append(providers, newExtensionProviderWrapper(ext)) - } - } - return providers -} - func (m *extensionManager) FindURLHandler(url string) *extensionProviderWrapper { m.mu.RLock() defer m.mu.RUnlock() @@ -252,21 +183,13 @@ func (m *extensionManager) GetPostProcessingProviders() []*extensionProviderWrap return providers } -// runPostProcessingCommon backs both RunPostProcessing (V1) and -// RunPostProcessingV2. V1 delegates into this shared loop with an equivalent -// PostProcessInput; preferV2 controls whether each hook is invoked via -// provider.PostProcessV2 or provider.PostProcess, so V1 keeps calling -// PostProcess (not PostProcessV2) exactly as it did before. -func (m *extensionManager) runPostProcessingCommon(input PostProcessInput, metadata map[string]any, preferV2 bool) (*PostProcessResult, error) { +func (m *extensionManager) RunPostProcessingV2(input PostProcessInput, metadata map[string]any) (*PostProcessResult, error) { providers := m.GetPostProcessingProviders() if len(providers) == 0 { return &PostProcessResult{Success: true, NewFilePath: input.Path, NewFileURI: input.URI}, nil } - logTag := "[PostProcess]" - if preferV2 { - logTag = "[PostProcessV2]" - } + logTag := "[PostProcessV2]" currentInput := input for _, provider := range providers { @@ -295,13 +218,7 @@ func (m *extensionManager) runPostProcessingCommon(input PostProcessInput, metad GoLog("%s Running hook %s from %s on %s\n", logTag, hook.ID, provider.extension.ID, currentInput.Path) - var result *PostProcessResult - var err error - if preferV2 { - result, err = provider.PostProcessV2(currentInput, metadata, hook.ID) - } else { - result, err = provider.PostProcess(currentInput.Path, metadata, hook.ID) - } + result, err := provider.PostProcessV2(currentInput, metadata, hook.ID) if err != nil { GoLog("%s Hook %s failed: %v\n", logTag, hook.ID, err) continue @@ -360,18 +277,6 @@ func validatePostProcessResult(ext *loadedExtension, input PostProcessInput, res return fmt.Errorf("replacement file path is outside allowed directories") } -func (m *extensionManager) RunPostProcessing(filePath string, metadata map[string]any) (*PostProcessResult, error) { - result, err := m.runPostProcessingCommon(PostProcessInput{Path: filePath}, metadata, false) - if err != nil { - return result, err - } - return &PostProcessResult{Success: result.Success, NewFilePath: result.NewFilePath}, nil -} - -func (m *extensionManager) RunPostProcessingV2(input PostProcessInput, metadata map[string]any) (*PostProcessResult, error) { - return m.runPostProcessingCommon(input, metadata, true) -} - func (m *extensionManager) GetLyricsProviders() []*extensionProviderWrapper { m.mu.RLock() defer m.mu.RUnlock() diff --git a/go_backend/progress.go b/go_backend/progress.go index c6a0cc43..0bc55690 100644 --- a/go_backend/progress.go +++ b/go_backend/progress.go @@ -108,25 +108,6 @@ func markMultiProgressDirtyIfChangedLocked(item *ItemProgress, before progressBr } } -func getProgress() DownloadProgress { - multiMu.RLock() - defer multiMu.RUnlock() - - for _, item := range multiProgress.Items { - return DownloadProgress{ - CurrentFile: item.ItemID, - Progress: item.Progress * 100, - BytesTotal: item.BytesTotal, - BytesReceived: item.BytesReceived, - IsDownloading: item.IsDownloading, - Status: item.Status, - Stage: item.Stage, - } - } - - return DownloadProgress{} -} - func GetMultiProgress() string { multiMu.RLock() if !multiProgressDirty { diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 2b3be14e..8f74d965 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -440,26 +440,10 @@ import Gobackend if let error = error { throw error } return response - case "getDownloadProgress": - let response = GobackendGetDownloadProgress() - return parseJsonPayload(response as String? ?? "{}") - case "getAllDownloadProgress": let response = GobackendGetAllDownloadProgress() return parseJsonPayload(response as String? ?? "{}") - case "initItemProgress": - let args = call.arguments as! [String: Any] - let itemId = args["item_id"] as! String - GobackendInitItemProgress(itemId) - return nil - - case "finishItemProgress": - let args = call.arguments as! [String: Any] - let itemId = args["item_id"] as! String - GobackendFinishItemProgress(itemId) - return nil - case "clearItemProgress": let args = call.arguments as! [String: Any] let itemId = args["item_id"] as! String @@ -498,14 +482,6 @@ import Gobackend GobackendSetAllowPrivateNetwork(allowed) return nil - case "checkDuplicate": - let args = call.arguments as! [String: Any] - let outputDir = args["output_dir"] as! String - let isrc = args["isrc"] as! String - let response = GobackendCheckDuplicate(outputDir, isrc, &error) - if let error = error { throw error } - return response - case "checkDuplicatesBatch": let args = call.arguments as! [String: Any] let outputDir = args["output_dir"] as! String @@ -541,16 +517,6 @@ import Gobackend let response = GobackendSanitizeFilename(filename) return response - case "fetchLyrics": - let args = call.arguments as! [String: Any] - let spotifyId = args["spotify_id"] as! String - let trackName = args["track_name"] as! String - let artistName = args["artist_name"] as! String - let durationMs = args["duration_ms"] as? Int64 ?? 0 - let response = GobackendFetchLyrics(spotifyId, trackName, artistName, durationMs, &error) - if let error = error { throw error } - return response - case "getLyricsLRC": let args = call.arguments as! [String: Any] let spotifyId = args["spotify_id"] as! String @@ -645,14 +611,6 @@ import Gobackend if let error = error { throw error } return response - case "getDeezerRelatedArtists": - let args = call.arguments as! [String: Any] - let artistId = args["artist_id"] as! String - let limit = args["limit"] as? Int ?? 12 - let response = GobackendGetDeezerRelatedArtists(artistId, Int(limit), &error) - if let error = error { throw error } - return response - case "getProviderMetadata": let args = call.arguments as! [String: Any] let providerId = args["provider_id"] as! String @@ -845,14 +803,6 @@ import Gobackend if let error = error { throw error } return response - case "searchTracksWithExtensions": - let args = call.arguments as! [String: Any] - let query = args["query"] as! String - let limit = args["limit"] as? Int ?? 20 - let response = GobackendSearchTracksWithExtensionsJSON(query, Int(limit), &error) - if let error = error { throw error } - return response - case "searchTracksWithMetadataProviders": let args = call.arguments as! [String: Any] let query = args["query"] as! String @@ -997,11 +947,6 @@ import Gobackend GobackendCancelExtensionRequestJSON(requestId) return nil - case "getSearchProviders": - let response = GobackendGetSearchProvidersJSON(&error) - if let error = error { throw error } - return response - case "handleURLWithExtension": let args = call.arguments as! [String: Any] let url = args["url"] as! String @@ -1015,19 +960,14 @@ import Gobackend let response = GobackendFindURLHandlerJSON(url) return response - case "getURLHandlers": - let response = GobackendGetURLHandlersJSON(&error) + case "getTrackPlatformLinks": + let args = call.arguments as! [String: Any] + let spotifyId = args["spotify_id"] as? String ?? "" + let isrc = args["isrc"] as? String ?? "" + let response = GobackendGetTrackPlatformLinksJSON(spotifyId, isrc, &error) if let error = error { throw error } return response - case "runPostProcessing": - let args = call.arguments as! [String: Any] - let filePath = args["file_path"] as! String - let metadataJson = args["metadata"] as? String ?? "" - let response = GobackendRunPostProcessingJSON(filePath, metadataJson, &error) - if let error = error { throw error } - return response - case "runPostProcessingV2": let args = call.arguments as! [String: Any] let inputJson = args["input"] as? String ?? "" @@ -1036,11 +976,6 @@ import Gobackend if let error = error { throw error } return response - case "getPostProcessingProviders": - let response = GobackendGetPostProcessingProvidersJSON(&error) - if let error = error { throw error } - return response - case "initExtensionRepo": let args = call.arguments as! [String: Any] let cacheDir = args["cache_dir"] as! String @@ -1106,13 +1041,6 @@ import Gobackend if let error = error { throw error } return response - case "getExtensionBrowseCategories": - let args = call.arguments as! [String: Any] - let extensionId = args["extension_id"] as! String - let response = GobackendGetExtensionBrowseCategoriesJSON(extensionId, &error) - if let error = error { throw error } - return response - case "setLibraryCoverCacheDir": let args = call.arguments as! [String: Any] let cacheDir = args["cache_dir"] as! String diff --git a/lib/services/platform_bridge.dart b/lib/services/platform_bridge.dart index 0b109ff9..1474078e 100644 --- a/lib/services/platform_bridge.dart +++ b/lib/services/platform_bridge.dart @@ -501,11 +501,6 @@ class PlatformBridge { return response; } - static Future> getDownloadProgress() async { - final result = await _channel.invokeMethod('getDownloadProgress'); - return _decodeMapResult(result); - } - static Future> getAllDownloadProgress() async { final result = await _channel.invokeMethod('getAllDownloadProgress'); return _decodeMapResult(result); @@ -521,14 +516,6 @@ class PlatformBridge { await _channel.invokeMethod('exitApp'); } - static Future initItemProgress(String itemId) async { - await _channel.invokeMethod('initItemProgress', {'item_id': itemId}); - } - - static Future finishItemProgress(String itemId) async { - await _channel.invokeMethod('finishItemProgress', {'item_id': itemId}); - } - static Future clearItemProgress(String itemId) async { await _channel.invokeMethod('clearItemProgress', {'item_id': itemId}); } @@ -578,13 +565,6 @@ class PlatformBridge { await _channel.invokeMethod('setAllowPrivateNetwork', {'allowed': allowed}); } - static Future> checkDuplicate( - String outputDir, - String isrc, - ) { - return _invokeMap('checkDuplicate', {'output_dir': outputDir, 'isrc': isrc}); - } - static Future buildFilename( String template, Map metadata, @@ -734,20 +714,6 @@ class PlatformBridge { return result as bool? ?? false; } - static Future> fetchLyrics( - String spotifyId, - String trackName, - String artistName, { - int durationMs = 0, - }) { - return _invokeMap('fetchLyrics', { - 'spotify_id': spotifyId, - 'track_name': trackName, - 'artist_name': artistName, - 'duration_ms': durationMs, - }); - } - static Future getLyricsLRC( String spotifyId, String trackName, @@ -1111,16 +1077,6 @@ class PlatformBridge { await _channel.invokeMethod('clearTrackCache'); } - static Future> getDeezerRelatedArtists( - String artistId, { - int limit = 12, - }) { - return _invokeMap('getDeezerRelatedArtists', { - 'artist_id': artistId, - 'limit': limit, - }); - } - static Future> getProviderMetadata( String providerId, String resourceType, @@ -1198,11 +1154,6 @@ class PlatformBridge { ); } - static Future>> getGoLogs() async { - final result = await _channel.invokeMethod('getLogs'); - return _decodeMapListResult(result, 'getGoLogs'); - } - static Future> getGoLogsSince(int index) async { final result = await _channel.invokeMethod('getLogsSince', { 'index': index, @@ -1395,18 +1346,6 @@ class PlatformBridge { return _decodeRequiredMapResult(result, 'invokeExtensionAction'); } - static Future>> searchTracksWithExtensions( - String query, { - int limit = 20, - }) async { - _log.d('searchTracksWithExtensions: "$query"'); - final result = await _channel.invokeMethod('searchTracksWithExtensions', { - 'query': query, - 'limit': limit, - }); - return _decodeMapListResult(result, 'searchTracksWithExtensions'); - } - static Future>> searchTracksWithMetadataProviders( String query, { int limit = 20, @@ -1602,11 +1541,6 @@ class PlatformBridge { } } - static Future>> getSearchProviders() async { - final result = await _channel.invokeMethod('getSearchProviders'); - return _decodeMapListResult(result, 'getSearchProviders'); - } - static Future?> handleURLWithExtension( String url, ) async { @@ -1727,9 +1661,22 @@ class PlatformBridge { return result as String; } - static Future>> getURLHandlers() async { - final result = await _channel.invokeMethod('getURLHandlers'); - return _decodeMapListResult(result, 'getURLHandlers'); + /// Streaming-platform links for a track, keyed by song.link platform ID. + /// Served from the Go-side memory cache; throws when the lookup fails. + static Future> getTrackPlatformLinks({ + String spotifyId = '', + String isrc = '', + }) async { + final result = await _channel.invokeMethod('getTrackPlatformLinks', { + 'spotify_id': spotifyId, + 'isrc': isrc, + }); + final decoded = _decodeMapResult(result); + final platforms = decoded['platforms']; + if (platforms is! Map) return const {}; + return platforms.map( + (key, value) => MapEntry(key.toString(), value.toString()), + ); } static Future?> getExtensionHomeFeed( @@ -1774,21 +1721,6 @@ class PlatformBridge { } } - static Future?> getExtensionBrowseCategories( - String extensionId, - ) async { - try { - final result = await _channel.invokeMethod( - 'getExtensionBrowseCategories', - {'extension_id': extensionId}, - ); - return _decodeNullableMapResult(result, 'getExtensionBrowseCategories'); - } catch (e) { - _log.e('getExtensionBrowseCategories failed: $e'); - return null; - } - } - static Future setLibraryCoverCacheDir(String cacheDir) async { _log.i('setLibraryCoverCacheDir: $cacheDir'); await _channel.invokeMethod('setLibraryCoverCacheDir', { @@ -2107,16 +2039,6 @@ class PlatformBridge { } } - static Future> runPostProcessing( - String filePath, { - Map? metadata, - }) { - return _invokeMap('runPostProcessing', { - 'file_path': filePath, - 'metadata': metadata != null ? jsonEncode(metadata) : '', - }); - } - static Future> runPostProcessingV2( String filePath, { Map? metadata, @@ -2133,11 +2055,6 @@ class PlatformBridge { }); } - static Future>> getPostProcessingProviders() async { - final result = await _channel.invokeMethod('getPostProcessingProviders'); - return _decodeMapListResult(result, 'getPostProcessingProviders'); - } - static Future initExtensionRepo(String cacheDir) async { _log.d('initExtensionRepo: $cacheDir'); await _channel.invokeMethod('initExtensionRepo', {'cache_dir': cacheDir});