Focus chrome was implemented twice, once in the focusable wrapper and once in the focus builders; both now go through FocusChrome. TvColorPicker's channel row was a copy of TvNumberSpinner and is now that widget in compact density. Also trims unused helpers and fields and simplifies the Jellyfin browse paths.
78 lines
2.6 KiB
Dart
78 lines
2.6 KiB
Dart
import 'package:json_annotation/json_annotation.dart';
|
|
|
|
import '../../media/media_server_user_profile.dart';
|
|
import '../../utils/json_utils.dart';
|
|
|
|
part 'plex_user_profile.g.dart';
|
|
|
|
/// Represents a Plex user's profile preferences
|
|
/// Fetched from https://clients.plex.tv/api/v2/user
|
|
///
|
|
/// Every field parses tolerantly: the account API drifts (~July 2026 the
|
|
/// language-list fields switched from arrays to CSV strings, #1488), and a
|
|
/// single drifted field must never sink the whole profile.
|
|
@JsonSerializable()
|
|
class PlexUserProfile implements MediaServerUserProfile {
|
|
@JsonKey(fromJson: _boolOrTrue)
|
|
@override
|
|
final bool autoSelectAudio;
|
|
@JsonKey(fromJson: flexibleIntOrZero)
|
|
final int defaultAudioAccessibility;
|
|
@JsonKey(fromJson: _flexibleLanguage)
|
|
@override
|
|
final String? defaultAudioLanguage;
|
|
@JsonKey(fromJson: flexibleCsvStringList)
|
|
@override
|
|
final List<String>? defaultAudioLanguages;
|
|
@JsonKey(fromJson: _flexibleLanguage)
|
|
@override
|
|
final String? defaultSubtitleLanguage;
|
|
@JsonKey(fromJson: flexibleCsvStringList)
|
|
@override
|
|
final List<String>? defaultSubtitleLanguages;
|
|
@JsonKey(fromJson: flexibleIntOrZero)
|
|
final int autoSelectSubtitle;
|
|
@JsonKey(fromJson: flexibleIntOrZero)
|
|
final int defaultSubtitleAccessibility;
|
|
@JsonKey(fromJson: _intOr1)
|
|
final int defaultSubtitleForced;
|
|
@JsonKey(fromJson: _intOr1)
|
|
final int watchedIndicator;
|
|
@JsonKey(fromJson: flexibleIntOrZero)
|
|
final int mediaReviewsVisibility;
|
|
@JsonKey(fromJson: flexibleCsvStringList)
|
|
final List<String>? mediaReviewsLanguages;
|
|
|
|
@override
|
|
SubtitlePlaybackMode? get subtitleMode => null;
|
|
|
|
PlexUserProfile({
|
|
required this.autoSelectAudio,
|
|
required this.defaultAudioAccessibility,
|
|
this.defaultAudioLanguage,
|
|
this.defaultAudioLanguages,
|
|
this.defaultSubtitleLanguage,
|
|
this.defaultSubtitleLanguages,
|
|
required this.autoSelectSubtitle,
|
|
required this.defaultSubtitleAccessibility,
|
|
required this.defaultSubtitleForced,
|
|
required this.watchedIndicator,
|
|
required this.mediaReviewsVisibility,
|
|
this.mediaReviewsLanguages,
|
|
});
|
|
|
|
factory PlexUserProfile.fromJson(Map<String, dynamic> json) {
|
|
final envelope = json['profile'];
|
|
final profile = envelope is Map<String, dynamic> ? envelope : json;
|
|
return _$PlexUserProfileFromJson(profile);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() => {'profile': _$PlexUserProfileToJson(this)};
|
|
}
|
|
|
|
/// Singular language fields tolerate the inverse drift (array/CSV → first entry).
|
|
String? _flexibleLanguage(Object? v) => flexibleCsvStringList(v)?.first;
|
|
|
|
bool _boolOrTrue(Object? v) => flexibleBoolNullable(v) ?? true;
|
|
int _intOr1(Object? v) => flexibleInt(v) ?? 1;
|