Files
plezy/lib/models/plex/plex_config.dart
T
edde746 6301d5124e chore(plex): send the JSON Accept header unconditionally
PlexConfig.acceptJson defaulted to true in both constructors and
travelled through copyWith, but no production or test caller ever passed
false, and every Plex path decodes JSON, so the header was conditional on
a flag that could not be off.

Emit `Accept: application/json` directly and drop the field. Headers on
the wire are unchanged.
2026-09-03 13:08:46 +02:00

112 lines
3.0 KiB
Dart

import 'package:package_info_plus/package_info_plus.dart';
import '../../utils/device_identity.dart';
class PlexConfig {
final String baseUrl;
final String? token;
final String clientIdentifier;
final String product;
final String version;
final String platform;
final String? device;
/// Friendly device name — Plex dashboards and Tautulli show it as the
/// session's "Player".
final String? deviceName;
final String? machineIdentifier;
final String? languageCode;
PlexConfig({
required this.baseUrl,
this.token,
required this.clientIdentifier,
required this.product,
required this.version,
this.platform = 'Flutter',
this.device,
this.deviceName,
this.machineIdentifier,
this.languageCode,
});
static Future<PlexConfig> create({
required String baseUrl,
String? token,
required String clientIdentifier,
String? product,
String? platform,
String? device,
String? machineIdentifier,
String? languageCode,
}) async {
final packageInfo = await PackageInfo.fromPlatform();
final identity = await DeviceIdentityService.resolve();
return PlexConfig(
baseUrl: baseUrl,
token: token,
clientIdentifier: clientIdentifier,
product: product ?? 'Plezy',
version: packageInfo.version,
platform: platform ?? identity.platform,
device: device ?? sanitizeHeaderValue(identity.deviceModel),
deviceName: sanitizeHeaderValue(identity.deviceName),
machineIdentifier: machineIdentifier,
languageCode: languageCode,
);
}
Map<String, String> get headers {
final headers = {
'X-Plex-Client-Identifier': clientIdentifier,
'X-Plex-Product': product,
'X-Plex-Version': version,
'X-Plex-Platform': platform,
'X-Plex-Client-Profile-Name': 'Generic',
'X-Plex-Device': ?device,
'X-Plex-Device-Name': ?deviceName,
'Accept': 'application/json',
'Accept-Charset': 'utf-8',
'Accept-Language': ?_normalizedLanguageCode,
'X-Plex-Language': ?_normalizedLanguageCode,
};
if (token != null) {
headers['X-Plex-Token'] = token!;
}
return headers;
}
String? get _normalizedLanguageCode {
final value = languageCode?.trim();
return value == null || value.isEmpty ? null : value;
}
PlexConfig copyWith({
String? baseUrl,
String? token,
String? clientIdentifier,
String? product,
String? version,
String? platform,
String? device,
String? deviceName,
String? machineIdentifier,
String? languageCode,
}) {
return PlexConfig(
baseUrl: baseUrl ?? this.baseUrl,
token: token ?? this.token,
clientIdentifier: clientIdentifier ?? this.clientIdentifier,
product: product ?? this.product,
version: version ?? this.version,
platform: platform ?? this.platform,
device: device ?? this.device,
deviceName: deviceName ?? this.deviceName,
machineIdentifier: machineIdentifier ?? this.machineIdentifier,
languageCode: languageCode ?? this.languageCode,
);
}
}