fix(metadata): send Accept-Language on Deezer requests so names follow the app language

Deezer localizes artist and genre names by IP geolocation when no language
is given, so users behind e.g. Arabic-region IPs got Arabic metadata on an
English device (VPN 'fixed' it). The app's display language is now pushed
to the backend and sent as Accept-Language, with an en-US default.

Fixes #480
This commit is contained in:
zarzet
2026-07-14 15:46:33 +07:00
parent 9ac10dd6bb
commit 3833a66bf6
5 changed files with 51 additions and 0 deletions
@@ -3152,6 +3152,13 @@ class MainActivity: FlutterFragmentActivity() {
}
result.success(null)
}
"setMetadataLanguage" -> {
val tag = call.argument<String>("tag") ?: ""
withContext(Dispatchers.IO) {
Gobackend.setMetadataLanguage(tag)
}
result.success(null)
}
"getLogCount" -> {
val count = withContext(Dispatchers.IO) {
Gobackend.getLogCount()
+4
View File
@@ -1321,6 +1321,10 @@ func (c *DeezerClient) doGetJSON(ctx context.Context, endpoint string, dst any)
}
req.Header.Set("Accept", "application/json")
// Without an explicit language Deezer localizes artist/genre names by
// the caller's IP geolocation (issue #480: Arabic metadata on an
// English device). Follow the app's display language instead.
req.Header.Set("Accept-Language", metadataAcceptLanguage())
resp, err := c.httpClient.Do(req)
if err != nil {
+25
View File
@@ -4,8 +4,33 @@ import (
"encoding/json"
"runtime/debug"
"strings"
"sync"
)
var (
metadataLanguageMu sync.RWMutex
metadataLanguageTag string
)
// SetMetadataLanguage sets the app's display language (BCP 47 tag, e.g.
// "en-US" or "id"), used as Accept-Language on metadata API requests so
// providers localize names by the app language instead of IP geolocation.
func SetMetadataLanguage(tag string) {
metadataLanguageMu.Lock()
metadataLanguageTag = strings.TrimSpace(tag)
metadataLanguageMu.Unlock()
}
func metadataAcceptLanguage() string {
metadataLanguageMu.RLock()
tag := metadataLanguageTag
metadataLanguageMu.RUnlock()
if tag == "" || strings.HasPrefix(strings.ToLower(tag), "en") {
return "en-US,en;q=0.9"
}
return tag + ",en;q=0.8"
}
// ReleaseMemory drops idle pooled extension runtimes, forces a GC, and
// returns freed heap to the OS. Called from the app on OS memory pressure and
// when backgrounded, so the Go side's RSS doesn't sit at its high-water mark
+7
View File
@@ -75,6 +75,13 @@ class _MainShellState extends ConsumerState<MainShell>
setPlaybackNormalizationEnabled(
ref.read(settingsProvider).playbackNormalization,
);
// Deezer & co. localize artist/genre names by IP unless told the app's
// language (issue #480).
unawaited(
PlatformBridge.setMetadataLanguage(
Localizations.localeOf(context).toLanguageTag(),
),
);
}
@override
+8
View File
@@ -1210,6 +1210,14 @@ class PlatformBridge {
} catch (_) {}
}
/// Tells the backend the app's display language so metadata providers
/// localize by it instead of IP geolocation. Best-effort.
static Future<void> setMetadataLanguage(String tag) async {
try {
await _channel.invokeMethod('setMetadataLanguage', {'tag': tag});
} catch (_) {}
}
static Future<int> getGoLogCount() async {
final result = await _channel.invokeMethod('getLogCount');
return result as int;