refactor: migrate models to freezed + json_serializable
This commit is contained in:
@@ -38,6 +38,15 @@ jobs:
|
||||
|
||||
flutter pub get
|
||||
|
||||
- name: Verify generated files committed
|
||||
run: |
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
if ! git diff --exit-code lib/; then
|
||||
echo "::error::Generated files (.g.dart / .freezed.dart) are out of date."
|
||||
echo "Run 'scripts/codegen.sh' and commit the result."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Verify formatting
|
||||
run: |
|
||||
# Find all Dart files excluding generated files
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
targets:
|
||||
$default:
|
||||
builders:
|
||||
json_serializable:
|
||||
options:
|
||||
create_to_json: true
|
||||
explicit_to_json: true
|
||||
field_rename: none
|
||||
include_if_null: true
|
||||
checked: false
|
||||
freezed:
|
||||
options:
|
||||
copy_with: true
|
||||
equal: true
|
||||
to_string: true
|
||||
@@ -1,114 +1,74 @@
|
||||
// ignore_for_file: invalid_annotation_target
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'media_kind.dart';
|
||||
|
||||
part 'library_query.freezed.dart';
|
||||
|
||||
/// Sort order applied to a library query.
|
||||
enum LibrarySortDirection { ascending, descending }
|
||||
|
||||
class LibrarySort {
|
||||
@freezed
|
||||
sealed class LibrarySort with _$LibrarySort {
|
||||
/// Backend-neutral sort field. Common values: `addedAt`, `originallyAvailableAt`,
|
||||
/// `lastViewedAt`, `title`, `rating`, `viewCount`, `random`.
|
||||
final String field;
|
||||
final LibrarySortDirection direction;
|
||||
|
||||
const LibrarySort({required this.field, this.direction = LibrarySortDirection.descending});
|
||||
const factory LibrarySort({
|
||||
required String field,
|
||||
@Default(LibrarySortDirection.descending) LibrarySortDirection direction,
|
||||
}) = _LibrarySort;
|
||||
}
|
||||
|
||||
/// A single filter clause. The semantics of `field` and `value` are
|
||||
/// backend-translated — the neutral query just carries the intent.
|
||||
class LibraryFilter {
|
||||
final String field;
|
||||
final String op; // "=", "!=", "contains", ">=", etc.
|
||||
final List<String> values;
|
||||
|
||||
const LibraryFilter({required this.field, this.op = '=', required this.values});
|
||||
@freezed
|
||||
sealed class LibraryFilter with _$LibraryFilter {
|
||||
const factory LibraryFilter({required String field, @Default('=') String op, required List<String> values}) =
|
||||
_LibraryFilter;
|
||||
}
|
||||
|
||||
/// Backend-neutral library content query. Each backend's adapter translates
|
||||
/// these into its own query DSL (Plex `/library/sections/{id}/all?type=...`
|
||||
/// or Jellyfin `/Items?ParentId=...&Filters=...`).
|
||||
class LibraryQuery {
|
||||
@freezed
|
||||
sealed class LibraryQuery with _$LibraryQuery {
|
||||
const factory LibraryQuery({
|
||||
/// Restrict to a single kind (e.g. `MediaKind.movie`). Null = library default.
|
||||
final MediaKind? kind;
|
||||
MediaKind? kind,
|
||||
|
||||
/// Pagination — zero-based offset.
|
||||
final int offset;
|
||||
final int limit;
|
||||
@Default(0) int offset,
|
||||
@Default(50) int limit,
|
||||
|
||||
final LibrarySort? sort;
|
||||
final List<LibraryFilter> filters;
|
||||
LibrarySort? sort,
|
||||
@Default(<LibraryFilter>[]) List<LibraryFilter> filters,
|
||||
|
||||
/// Free-text search restricted to this library. Distinct from the global
|
||||
/// search endpoint.
|
||||
final String? search;
|
||||
String? search,
|
||||
|
||||
/// Whether to include items the active user has already watched.
|
||||
final bool includeWatched;
|
||||
@Default(true) bool includeWatched,
|
||||
|
||||
/// Restrict the result to items whose sort name starts with this string —
|
||||
/// the alpha-jump bar's filter UX. The literal `#` is a sentinel for
|
||||
/// "non-alphabetic" and translates to a `NameLessThan=A` query for backends
|
||||
/// that support it.
|
||||
final String? nameStartsWith;
|
||||
String? nameStartsWith,
|
||||
|
||||
/// Genre filter — used by the per-library filter sheet. Backends that
|
||||
/// take multiple values (Jellyfin) AND/intersect; those that take one
|
||||
/// (Plex's existing flow) consult `filters` instead.
|
||||
final List<String>? genres;
|
||||
final List<String>? officialRatings;
|
||||
final List<int>? years;
|
||||
final List<String>? tags;
|
||||
|
||||
const LibraryQuery({
|
||||
this.kind,
|
||||
this.offset = 0,
|
||||
this.limit = 50,
|
||||
this.sort,
|
||||
this.filters = const [],
|
||||
this.search,
|
||||
this.includeWatched = true,
|
||||
this.nameStartsWith,
|
||||
this.genres,
|
||||
this.officialRatings,
|
||||
this.years,
|
||||
this.tags,
|
||||
});
|
||||
|
||||
LibraryQuery copyWith({
|
||||
MediaKind? kind,
|
||||
int? offset,
|
||||
int? limit,
|
||||
LibrarySort? sort,
|
||||
List<LibraryFilter>? filters,
|
||||
String? search,
|
||||
bool? includeWatched,
|
||||
String? nameStartsWith,
|
||||
List<String>? genres,
|
||||
List<String>? officialRatings,
|
||||
List<int>? years,
|
||||
List<String>? tags,
|
||||
}) {
|
||||
return LibraryQuery(
|
||||
kind: kind ?? this.kind,
|
||||
offset: offset ?? this.offset,
|
||||
limit: limit ?? this.limit,
|
||||
sort: sort ?? this.sort,
|
||||
filters: filters ?? this.filters,
|
||||
search: search ?? this.search,
|
||||
includeWatched: includeWatched ?? this.includeWatched,
|
||||
nameStartsWith: nameStartsWith ?? this.nameStartsWith,
|
||||
genres: genres ?? this.genres,
|
||||
officialRatings: officialRatings ?? this.officialRatings,
|
||||
years: years ?? this.years,
|
||||
tags: tags ?? this.tags,
|
||||
);
|
||||
}
|
||||
}) = _LibraryQuery;
|
||||
}
|
||||
|
||||
/// Page of items returned by [MediaServerClient.getLibraryContent].
|
||||
/// Carries the total count so the UI can render correct pagination affordances.
|
||||
class LibraryPage<T> {
|
||||
final List<T> items;
|
||||
final int totalCount;
|
||||
final int offset;
|
||||
|
||||
const LibraryPage({required this.items, required this.totalCount, this.offset = 0});
|
||||
@freezed
|
||||
sealed class LibraryPage<T> with _$LibraryPage<T> {
|
||||
const factory LibraryPage({required List<T> items, required int totalCount, @Default(0) int offset}) =
|
||||
_LibraryPage<T>;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,17 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'media_sort.freezed.dart';
|
||||
part 'media_sort.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class MediaSort {
|
||||
final String key;
|
||||
final String? descKey;
|
||||
final String title;
|
||||
final String? defaultDirection;
|
||||
@freezed
|
||||
sealed class MediaSort with _$MediaSort {
|
||||
const MediaSort._();
|
||||
|
||||
MediaSort({required this.key, this.descKey, required this.title, this.defaultDirection});
|
||||
const factory MediaSort({required String key, String? descKey, required String title, String? defaultDirection}) =
|
||||
_MediaSort;
|
||||
|
||||
factory MediaSort.fromJson(Map<String, dynamic> json) => _$MediaSortFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$MediaSortToJson(this);
|
||||
|
||||
String getSortKey({bool descending = false}) {
|
||||
if (!descending) {
|
||||
return key;
|
||||
@@ -26,18 +23,4 @@ class MediaSort {
|
||||
bool get isDefaultDescending {
|
||||
return defaultDirection?.toLowerCase() == 'desc';
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MediaSort(key: $key, title: $title, defaultDirection: $defaultDirection)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
return other is MediaSort && other.key == key;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => key.hashCode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'media_sort.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MediaSort {
|
||||
|
||||
String get key; String? get descKey; String get title; String? get defaultDirection;
|
||||
/// Create a copy of MediaSort
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$MediaSortCopyWith<MediaSort> get copyWith => _$MediaSortCopyWithImpl<MediaSort>(this as MediaSort, _$identity);
|
||||
|
||||
/// Serializes this MediaSort to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is MediaSort&&(identical(other.key, key) || other.key == key)&&(identical(other.descKey, descKey) || other.descKey == descKey)&&(identical(other.title, title) || other.title == title)&&(identical(other.defaultDirection, defaultDirection) || other.defaultDirection == defaultDirection));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,key,descKey,title,defaultDirection);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MediaSort(key: $key, descKey: $descKey, title: $title, defaultDirection: $defaultDirection)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $MediaSortCopyWith<$Res> {
|
||||
factory $MediaSortCopyWith(MediaSort value, $Res Function(MediaSort) _then) = _$MediaSortCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String key, String? descKey, String title, String? defaultDirection
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$MediaSortCopyWithImpl<$Res>
|
||||
implements $MediaSortCopyWith<$Res> {
|
||||
_$MediaSortCopyWithImpl(this._self, this._then);
|
||||
|
||||
final MediaSort _self;
|
||||
final $Res Function(MediaSort) _then;
|
||||
|
||||
/// Create a copy of MediaSort
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? key = null,Object? descKey = freezed,Object? title = null,Object? defaultDirection = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
key: null == key ? _self.key : key // ignore: cast_nullable_to_non_nullable
|
||||
as String,descKey: freezed == descKey ? _self.descKey : descKey // ignore: cast_nullable_to_non_nullable
|
||||
as String?,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,defaultDirection: freezed == defaultDirection ? _self.defaultDirection : defaultDirection // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [MediaSort].
|
||||
extension MediaSortPatterns on MediaSort {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _MediaSort value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MediaSort() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _MediaSort value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MediaSort():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _MediaSort value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MediaSort() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String key, String? descKey, String title, String? defaultDirection)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MediaSort() when $default != null:
|
||||
return $default(_that.key,_that.descKey,_that.title,_that.defaultDirection);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String key, String? descKey, String title, String? defaultDirection) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MediaSort():
|
||||
return $default(_that.key,_that.descKey,_that.title,_that.defaultDirection);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String key, String? descKey, String title, String? defaultDirection)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MediaSort() when $default != null:
|
||||
return $default(_that.key,_that.descKey,_that.title,_that.defaultDirection);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _MediaSort extends MediaSort {
|
||||
const _MediaSort({required this.key, this.descKey, required this.title, this.defaultDirection}): super._();
|
||||
factory _MediaSort.fromJson(Map<String, dynamic> json) => _$MediaSortFromJson(json);
|
||||
|
||||
@override final String key;
|
||||
@override final String? descKey;
|
||||
@override final String title;
|
||||
@override final String? defaultDirection;
|
||||
|
||||
/// Create a copy of MediaSort
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$MediaSortCopyWith<_MediaSort> get copyWith => __$MediaSortCopyWithImpl<_MediaSort>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$MediaSortToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MediaSort&&(identical(other.key, key) || other.key == key)&&(identical(other.descKey, descKey) || other.descKey == descKey)&&(identical(other.title, title) || other.title == title)&&(identical(other.defaultDirection, defaultDirection) || other.defaultDirection == defaultDirection));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,key,descKey,title,defaultDirection);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MediaSort(key: $key, descKey: $descKey, title: $title, defaultDirection: $defaultDirection)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$MediaSortCopyWith<$Res> implements $MediaSortCopyWith<$Res> {
|
||||
factory _$MediaSortCopyWith(_MediaSort value, $Res Function(_MediaSort) _then) = __$MediaSortCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String key, String? descKey, String title, String? defaultDirection
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$MediaSortCopyWithImpl<$Res>
|
||||
implements _$MediaSortCopyWith<$Res> {
|
||||
__$MediaSortCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _MediaSort _self;
|
||||
final $Res Function(_MediaSort) _then;
|
||||
|
||||
/// Create a copy of MediaSort
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? key = null,Object? descKey = freezed,Object? title = null,Object? defaultDirection = freezed,}) {
|
||||
return _then(_MediaSort(
|
||||
key: null == key ? _self.key : key // ignore: cast_nullable_to_non_nullable
|
||||
as String,descKey: freezed == descKey ? _self.descKey : descKey // ignore: cast_nullable_to_non_nullable
|
||||
as String?,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,defaultDirection: freezed == defaultDirection ? _self.defaultDirection : defaultDirection // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -6,16 +6,17 @@ part of 'media_sort.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
MediaSort _$MediaSortFromJson(Map<String, dynamic> json) => MediaSort(
|
||||
_MediaSort _$MediaSortFromJson(Map<String, dynamic> json) => _MediaSort(
|
||||
key: json['key'] as String,
|
||||
descKey: json['descKey'] as String?,
|
||||
title: json['title'] as String,
|
||||
defaultDirection: json['defaultDirection'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MediaSortToJson(MediaSort instance) => <String, dynamic>{
|
||||
Map<String, dynamic> _$MediaSortToJson(_MediaSort instance) =>
|
||||
<String, dynamic>{
|
||||
'key': instance.key,
|
||||
'descKey': instance.descKey,
|
||||
'title': instance.title,
|
||||
'defaultDirection': instance.defaultDirection,
|
||||
};
|
||||
};
|
||||
|
||||
+40
-101
@@ -1,122 +1,61 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'media_item.dart';
|
||||
|
||||
part 'play_queue.freezed.dart';
|
||||
|
||||
/// Backend-neutral play queue — a flat ordered list of items with a current
|
||||
/// cursor. Implementations differ in whether the queue is server-resourced
|
||||
/// (Plex) or client-only (Jellyfin).
|
||||
sealed class PlayQueue {
|
||||
/// Items in playback order.
|
||||
List<MediaItem> get items;
|
||||
@freezed
|
||||
sealed class PlayQueue with _$PlayQueue {
|
||||
const PlayQueue._();
|
||||
|
||||
/// Index of the currently-playing item, or `null` if the queue has not
|
||||
/// started.
|
||||
int? get currentIndex;
|
||||
|
||||
/// Whether the queue has been shuffled.
|
||||
bool get shuffled;
|
||||
|
||||
/// Backend that minted this queue.
|
||||
String get backendId;
|
||||
|
||||
MediaItem? get current =>
|
||||
currentIndex != null && currentIndex! >= 0 && currentIndex! < items.length ? items[currentIndex!] : null;
|
||||
|
||||
bool get hasNext => currentIndex != null && currentIndex! + 1 < items.length;
|
||||
bool get hasPrevious => currentIndex != null && currentIndex! > 0;
|
||||
}
|
||||
|
||||
/// Plex play queue — coordinated server-side via `/playQueues` so multiple
|
||||
/// devices can view/control the same queue.
|
||||
class PlexServerPlayQueue extends PlayQueue {
|
||||
/// Plex play queue — coordinated server-side via `/playQueues` so multiple
|
||||
/// devices can view/control the same queue.
|
||||
const factory PlayQueue.plex({
|
||||
/// Plex `playQueueID` — addresses the queue for subsequent fetches.
|
||||
final int playQueueId;
|
||||
|
||||
@override
|
||||
final List<MediaItem> items;
|
||||
|
||||
@override
|
||||
final int? currentIndex;
|
||||
|
||||
@override
|
||||
final bool shuffled;
|
||||
required int playQueueId,
|
||||
required List<MediaItem> items,
|
||||
int? currentIndex,
|
||||
@Default(false) bool shuffled,
|
||||
|
||||
/// Plex `playQueueSelectedItemID` of the active item.
|
||||
final int? selectedItemId;
|
||||
int? selectedItemId,
|
||||
|
||||
/// Plex `playQueueVersion` — server-side optimistic concurrency token.
|
||||
final int? version;
|
||||
int? version,
|
||||
|
||||
/// Plex `playQueueSourceURI` — used for "Up Next" derivation.
|
||||
final String? sourceUri;
|
||||
|
||||
PlexServerPlayQueue({
|
||||
required this.playQueueId,
|
||||
required this.items,
|
||||
this.currentIndex,
|
||||
this.shuffled = false,
|
||||
this.selectedItemId,
|
||||
this.version,
|
||||
this.sourceUri,
|
||||
});
|
||||
|
||||
@override
|
||||
String get backendId => 'plex';
|
||||
|
||||
PlexServerPlayQueue copyWith({
|
||||
int? playQueueId,
|
||||
List<MediaItem>? items,
|
||||
int? currentIndex,
|
||||
bool? shuffled,
|
||||
int? selectedItemId,
|
||||
int? version,
|
||||
String? sourceUri,
|
||||
}) {
|
||||
return PlexServerPlayQueue(
|
||||
playQueueId: playQueueId ?? this.playQueueId,
|
||||
items: items ?? this.items,
|
||||
currentIndex: currentIndex ?? this.currentIndex,
|
||||
shuffled: shuffled ?? this.shuffled,
|
||||
selectedItemId: selectedItemId ?? this.selectedItemId,
|
||||
version: version ?? this.version,
|
||||
sourceUri: sourceUri ?? this.sourceUri,
|
||||
);
|
||||
}
|
||||
}
|
||||
}) = PlexServerPlayQueue;
|
||||
|
||||
/// Client-only play queue used by Jellyfin and any backend without a
|
||||
/// server-side queue concept. Each [LocalPlayQueue] is anchored by a
|
||||
/// client-generated UUID so callers can address it like a Plex queue.
|
||||
class LocalPlayQueue extends PlayQueue {
|
||||
/// Client-only play queue used by Jellyfin and any backend without a
|
||||
/// server-side queue concept. Each [LocalPlayQueue] is anchored by a
|
||||
/// client-generated UUID so callers can address it like a Plex queue.
|
||||
const factory PlayQueue.local({
|
||||
/// Client-generated UUID identifying this queue for the session.
|
||||
final String id;
|
||||
|
||||
@override
|
||||
final List<MediaItem> items;
|
||||
|
||||
@override
|
||||
final int? currentIndex;
|
||||
|
||||
@override
|
||||
final bool shuffled;
|
||||
required String id,
|
||||
required List<MediaItem> items,
|
||||
|
||||
/// Server kind that owns this queue's items (typically `"jellyfin"`).
|
||||
@override
|
||||
final String backendId;
|
||||
required String backendId,
|
||||
int? currentIndex,
|
||||
@Default(false) bool shuffled,
|
||||
}) = LocalPlayQueue;
|
||||
|
||||
LocalPlayQueue({
|
||||
required this.id,
|
||||
required this.items,
|
||||
required this.backendId,
|
||||
this.currentIndex,
|
||||
this.shuffled = false,
|
||||
});
|
||||
MediaItem? get current => switch (this) {
|
||||
PlexServerPlayQueue(:final items, :final currentIndex) || LocalPlayQueue(:final items, :final currentIndex) =>
|
||||
currentIndex != null && currentIndex >= 0 && currentIndex < items.length ? items[currentIndex] : null,
|
||||
};
|
||||
|
||||
LocalPlayQueue copyWith({String? id, List<MediaItem>? items, int? currentIndex, bool? shuffled, String? backendId}) {
|
||||
return LocalPlayQueue(
|
||||
id: id ?? this.id,
|
||||
items: items ?? this.items,
|
||||
currentIndex: currentIndex ?? this.currentIndex,
|
||||
shuffled: shuffled ?? this.shuffled,
|
||||
backendId: backendId ?? this.backendId,
|
||||
);
|
||||
}
|
||||
bool get hasNext => switch (this) {
|
||||
PlexServerPlayQueue(:final items, :final currentIndex) ||
|
||||
LocalPlayQueue(:final items, :final currentIndex) => currentIndex != null && currentIndex + 1 < items.length,
|
||||
};
|
||||
|
||||
bool get hasPrevious => switch (this) {
|
||||
PlexServerPlayQueue(:final currentIndex) ||
|
||||
LocalPlayQueue(:final currentIndex) => currentIndex != null && currentIndex > 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'play_queue.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$PlayQueue {
|
||||
|
||||
List<MediaItem> get items; int? get currentIndex; bool get shuffled;
|
||||
/// Create a copy of PlayQueue
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$PlayQueueCopyWith<PlayQueue> get copyWith => _$PlayQueueCopyWithImpl<PlayQueue>(this as PlayQueue, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PlayQueue&&const DeepCollectionEquality().equals(other.items, items)&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&(identical(other.shuffled, shuffled) || other.shuffled == shuffled));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(items),currentIndex,shuffled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlayQueue(items: $items, currentIndex: $currentIndex, shuffled: $shuffled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $PlayQueueCopyWith<$Res> {
|
||||
factory $PlayQueueCopyWith(PlayQueue value, $Res Function(PlayQueue) _then) = _$PlayQueueCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
List<MediaItem> items, int? currentIndex, bool shuffled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$PlayQueueCopyWithImpl<$Res>
|
||||
implements $PlayQueueCopyWith<$Res> {
|
||||
_$PlayQueueCopyWithImpl(this._self, this._then);
|
||||
|
||||
final PlayQueue _self;
|
||||
final $Res Function(PlayQueue) _then;
|
||||
|
||||
/// Create a copy of PlayQueue
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? items = null,Object? currentIndex = freezed,Object? shuffled = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
|
||||
as List<MediaItem>,currentIndex: freezed == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int?,shuffled: null == shuffled ? _self.shuffled : shuffled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [PlayQueue].
|
||||
extension PlayQueuePatterns on PlayQueue {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( PlexServerPlayQueue value)? plex,TResult Function( LocalPlayQueue value)? local,required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case PlexServerPlayQueue() when plex != null:
|
||||
return plex(_that);case LocalPlayQueue() when local != null:
|
||||
return local(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( PlexServerPlayQueue value) plex,required TResult Function( LocalPlayQueue value) local,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case PlexServerPlayQueue():
|
||||
return plex(_that);case LocalPlayQueue():
|
||||
return local(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( PlexServerPlayQueue value)? plex,TResult? Function( LocalPlayQueue value)? local,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case PlexServerPlayQueue() when plex != null:
|
||||
return plex(_that);case LocalPlayQueue() when local != null:
|
||||
return local(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( int playQueueId, List<MediaItem> items, int? currentIndex, bool shuffled, int? selectedItemId, int? version, String? sourceUri)? plex,TResult Function( String id, List<MediaItem> items, String backendId, int? currentIndex, bool shuffled)? local,required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case PlexServerPlayQueue() when plex != null:
|
||||
return plex(_that.playQueueId,_that.items,_that.currentIndex,_that.shuffled,_that.selectedItemId,_that.version,_that.sourceUri);case LocalPlayQueue() when local != null:
|
||||
return local(_that.id,_that.items,_that.backendId,_that.currentIndex,_that.shuffled);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( int playQueueId, List<MediaItem> items, int? currentIndex, bool shuffled, int? selectedItemId, int? version, String? sourceUri) plex,required TResult Function( String id, List<MediaItem> items, String backendId, int? currentIndex, bool shuffled) local,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case PlexServerPlayQueue():
|
||||
return plex(_that.playQueueId,_that.items,_that.currentIndex,_that.shuffled,_that.selectedItemId,_that.version,_that.sourceUri);case LocalPlayQueue():
|
||||
return local(_that.id,_that.items,_that.backendId,_that.currentIndex,_that.shuffled);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( int playQueueId, List<MediaItem> items, int? currentIndex, bool shuffled, int? selectedItemId, int? version, String? sourceUri)? plex,TResult? Function( String id, List<MediaItem> items, String backendId, int? currentIndex, bool shuffled)? local,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case PlexServerPlayQueue() when plex != null:
|
||||
return plex(_that.playQueueId,_that.items,_that.currentIndex,_that.shuffled,_that.selectedItemId,_that.version,_that.sourceUri);case LocalPlayQueue() when local != null:
|
||||
return local(_that.id,_that.items,_that.backendId,_that.currentIndex,_that.shuffled);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class PlexServerPlayQueue extends PlayQueue {
|
||||
const PlexServerPlayQueue({required this.playQueueId, required final List<MediaItem> items, this.currentIndex, this.shuffled = false, this.selectedItemId, this.version, this.sourceUri}): _items = items,super._();
|
||||
|
||||
|
||||
/// Plex `playQueueID` — addresses the queue for subsequent fetches.
|
||||
final int playQueueId;
|
||||
final List<MediaItem> _items;
|
||||
@override List<MediaItem> get items {
|
||||
if (_items is EqualUnmodifiableListView) return _items;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_items);
|
||||
}
|
||||
|
||||
@override final int? currentIndex;
|
||||
@override@JsonKey() final bool shuffled;
|
||||
/// Plex `playQueueSelectedItemID` of the active item.
|
||||
final int? selectedItemId;
|
||||
/// Plex `playQueueVersion` — server-side optimistic concurrency token.
|
||||
final int? version;
|
||||
/// Plex `playQueueSourceURI` — used for "Up Next" derivation.
|
||||
final String? sourceUri;
|
||||
|
||||
/// Create a copy of PlayQueue
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$PlexServerPlayQueueCopyWith<PlexServerPlayQueue> get copyWith => _$PlexServerPlayQueueCopyWithImpl<PlexServerPlayQueue>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PlexServerPlayQueue&&(identical(other.playQueueId, playQueueId) || other.playQueueId == playQueueId)&&const DeepCollectionEquality().equals(other._items, _items)&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&(identical(other.shuffled, shuffled) || other.shuffled == shuffled)&&(identical(other.selectedItemId, selectedItemId) || other.selectedItemId == selectedItemId)&&(identical(other.version, version) || other.version == version)&&(identical(other.sourceUri, sourceUri) || other.sourceUri == sourceUri));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,playQueueId,const DeepCollectionEquality().hash(_items),currentIndex,shuffled,selectedItemId,version,sourceUri);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlayQueue.plex(playQueueId: $playQueueId, items: $items, currentIndex: $currentIndex, shuffled: $shuffled, selectedItemId: $selectedItemId, version: $version, sourceUri: $sourceUri)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $PlexServerPlayQueueCopyWith<$Res> implements $PlayQueueCopyWith<$Res> {
|
||||
factory $PlexServerPlayQueueCopyWith(PlexServerPlayQueue value, $Res Function(PlexServerPlayQueue) _then) = _$PlexServerPlayQueueCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int playQueueId, List<MediaItem> items, int? currentIndex, bool shuffled, int? selectedItemId, int? version, String? sourceUri
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$PlexServerPlayQueueCopyWithImpl<$Res>
|
||||
implements $PlexServerPlayQueueCopyWith<$Res> {
|
||||
_$PlexServerPlayQueueCopyWithImpl(this._self, this._then);
|
||||
|
||||
final PlexServerPlayQueue _self;
|
||||
final $Res Function(PlexServerPlayQueue) _then;
|
||||
|
||||
/// Create a copy of PlayQueue
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? playQueueId = null,Object? items = null,Object? currentIndex = freezed,Object? shuffled = null,Object? selectedItemId = freezed,Object? version = freezed,Object? sourceUri = freezed,}) {
|
||||
return _then(PlexServerPlayQueue(
|
||||
playQueueId: null == playQueueId ? _self.playQueueId : playQueueId // ignore: cast_nullable_to_non_nullable
|
||||
as int,items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||
as List<MediaItem>,currentIndex: freezed == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int?,shuffled: null == shuffled ? _self.shuffled : shuffled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,selectedItemId: freezed == selectedItemId ? _self.selectedItemId : selectedItemId // ignore: cast_nullable_to_non_nullable
|
||||
as int?,version: freezed == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as int?,sourceUri: freezed == sourceUri ? _self.sourceUri : sourceUri // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class LocalPlayQueue extends PlayQueue {
|
||||
const LocalPlayQueue({required this.id, required final List<MediaItem> items, required this.backendId, this.currentIndex, this.shuffled = false}): _items = items,super._();
|
||||
|
||||
|
||||
/// Client-generated UUID identifying this queue for the session.
|
||||
final String id;
|
||||
final List<MediaItem> _items;
|
||||
@override List<MediaItem> get items {
|
||||
if (_items is EqualUnmodifiableListView) return _items;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_items);
|
||||
}
|
||||
|
||||
/// Server kind that owns this queue's items (typically `"jellyfin"`).
|
||||
final String backendId;
|
||||
@override final int? currentIndex;
|
||||
@override@JsonKey() final bool shuffled;
|
||||
|
||||
/// Create a copy of PlayQueue
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$LocalPlayQueueCopyWith<LocalPlayQueue> get copyWith => _$LocalPlayQueueCopyWithImpl<LocalPlayQueue>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is LocalPlayQueue&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other._items, _items)&&(identical(other.backendId, backendId) || other.backendId == backendId)&&(identical(other.currentIndex, currentIndex) || other.currentIndex == currentIndex)&&(identical(other.shuffled, shuffled) || other.shuffled == shuffled));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(_items),backendId,currentIndex,shuffled);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlayQueue.local(id: $id, items: $items, backendId: $backendId, currentIndex: $currentIndex, shuffled: $shuffled)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $LocalPlayQueueCopyWith<$Res> implements $PlayQueueCopyWith<$Res> {
|
||||
factory $LocalPlayQueueCopyWith(LocalPlayQueue value, $Res Function(LocalPlayQueue) _then) = _$LocalPlayQueueCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, List<MediaItem> items, String backendId, int? currentIndex, bool shuffled
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$LocalPlayQueueCopyWithImpl<$Res>
|
||||
implements $LocalPlayQueueCopyWith<$Res> {
|
||||
_$LocalPlayQueueCopyWithImpl(this._self, this._then);
|
||||
|
||||
final LocalPlayQueue _self;
|
||||
final $Res Function(LocalPlayQueue) _then;
|
||||
|
||||
/// Create a copy of PlayQueue
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? items = null,Object? backendId = null,Object? currentIndex = freezed,Object? shuffled = null,}) {
|
||||
return _then(LocalPlayQueue(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||
as List<MediaItem>,backendId: null == backendId ? _self.backendId : backendId // ignore: cast_nullable_to_non_nullable
|
||||
as String,currentIndex: freezed == currentIndex ? _self.currentIndex : currentIndex // ignore: cast_nullable_to_non_nullable
|
||||
as int?,shuffled: null == shuffled ? _self.shuffled : shuffled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,3 +1,11 @@
|
||||
// ignore_for_file: invalid_annotation_target
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../../utils/json_converters.dart';
|
||||
|
||||
part 'remote_command.freezed.dart';
|
||||
part 'remote_command.g.dart';
|
||||
|
||||
enum RemoteCommandType {
|
||||
dpadUp,
|
||||
dpadDown,
|
||||
@@ -46,24 +54,16 @@ enum RemoteCommandType {
|
||||
syncState,
|
||||
}
|
||||
|
||||
class RemoteCommand {
|
||||
final RemoteCommandType type;
|
||||
final Map<String, dynamic>? data;
|
||||
|
||||
const RemoteCommand({required this.type, this.data});
|
||||
|
||||
factory RemoteCommand.fromJson(Map<String, dynamic> json) {
|
||||
final index = json['t'] as int;
|
||||
return RemoteCommand(
|
||||
type: index < RemoteCommandType.values.length ? RemoteCommandType.values[index] : RemoteCommandType.ping,
|
||||
data: json['d'] as Map<String, dynamic>?,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'t': type.index, if (data != null) 'd': data};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'RemoteCommand(${type.name}, data: $data)';
|
||||
class _RemoteCommandTypeConverter extends IndexedEnumConverter<RemoteCommandType> {
|
||||
const _RemoteCommandTypeConverter() : super(RemoteCommandType.values, RemoteCommandType.ping);
|
||||
}
|
||||
|
||||
@freezed
|
||||
sealed class RemoteCommand with _$RemoteCommand {
|
||||
const factory RemoteCommand({
|
||||
@JsonKey(name: 't') @_RemoteCommandTypeConverter() required RemoteCommandType type,
|
||||
@JsonKey(name: 'd') Map<String, dynamic>? data,
|
||||
}) = _RemoteCommand;
|
||||
|
||||
factory RemoteCommand.fromJson(Map<String, dynamic> json) => _$RemoteCommandFromJson(json);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'remote_command.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$RemoteCommand {
|
||||
|
||||
@JsonKey(name: 't')@_RemoteCommandTypeConverter() RemoteCommandType get type;@JsonKey(name: 'd') Map<String, dynamic>? get data;
|
||||
/// Create a copy of RemoteCommand
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$RemoteCommandCopyWith<RemoteCommand> get copyWith => _$RemoteCommandCopyWithImpl<RemoteCommand>(this as RemoteCommand, _$identity);
|
||||
|
||||
/// Serializes this RemoteCommand to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is RemoteCommand&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.data, data));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(data));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RemoteCommand(type: $type, data: $data)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $RemoteCommandCopyWith<$Res> {
|
||||
factory $RemoteCommandCopyWith(RemoteCommand value, $Res Function(RemoteCommand) _then) = _$RemoteCommandCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 't')@_RemoteCommandTypeConverter() RemoteCommandType type,@JsonKey(name: 'd') Map<String, dynamic>? data
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$RemoteCommandCopyWithImpl<$Res>
|
||||
implements $RemoteCommandCopyWith<$Res> {
|
||||
_$RemoteCommandCopyWithImpl(this._self, this._then);
|
||||
|
||||
final RemoteCommand _self;
|
||||
final $Res Function(RemoteCommand) _then;
|
||||
|
||||
/// Create a copy of RemoteCommand
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? data = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteCommandType,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [RemoteCommand].
|
||||
extension RemoteCommandPatterns on RemoteCommand {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _RemoteCommand value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteCommand() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _RemoteCommand value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteCommand():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _RemoteCommand value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteCommand() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function(@JsonKey(name: 't')@_RemoteCommandTypeConverter() RemoteCommandType type, @JsonKey(name: 'd') Map<String, dynamic>? data)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteCommand() when $default != null:
|
||||
return $default(_that.type,_that.data);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function(@JsonKey(name: 't')@_RemoteCommandTypeConverter() RemoteCommandType type, @JsonKey(name: 'd') Map<String, dynamic>? data) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteCommand():
|
||||
return $default(_that.type,_that.data);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function(@JsonKey(name: 't')@_RemoteCommandTypeConverter() RemoteCommandType type, @JsonKey(name: 'd') Map<String, dynamic>? data)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteCommand() when $default != null:
|
||||
return $default(_that.type,_that.data);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _RemoteCommand implements RemoteCommand {
|
||||
const _RemoteCommand({@JsonKey(name: 't')@_RemoteCommandTypeConverter() required this.type, @JsonKey(name: 'd') final Map<String, dynamic>? data}): _data = data;
|
||||
factory _RemoteCommand.fromJson(Map<String, dynamic> json) => _$RemoteCommandFromJson(json);
|
||||
|
||||
@override@JsonKey(name: 't')@_RemoteCommandTypeConverter() final RemoteCommandType type;
|
||||
final Map<String, dynamic>? _data;
|
||||
@override@JsonKey(name: 'd') Map<String, dynamic>? get data {
|
||||
final value = _data;
|
||||
if (value == null) return null;
|
||||
if (_data is EqualUnmodifiableMapView) return _data;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of RemoteCommand
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$RemoteCommandCopyWith<_RemoteCommand> get copyWith => __$RemoteCommandCopyWithImpl<_RemoteCommand>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$RemoteCommandToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RemoteCommand&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._data, _data));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,type,const DeepCollectionEquality().hash(_data));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RemoteCommand(type: $type, data: $data)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$RemoteCommandCopyWith<$Res> implements $RemoteCommandCopyWith<$Res> {
|
||||
factory _$RemoteCommandCopyWith(_RemoteCommand value, $Res Function(_RemoteCommand) _then) = __$RemoteCommandCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
@JsonKey(name: 't')@_RemoteCommandTypeConverter() RemoteCommandType type,@JsonKey(name: 'd') Map<String, dynamic>? data
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$RemoteCommandCopyWithImpl<$Res>
|
||||
implements _$RemoteCommandCopyWith<$Res> {
|
||||
__$RemoteCommandCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _RemoteCommand _self;
|
||||
final $Res Function(_RemoteCommand) _then;
|
||||
|
||||
/// Create a copy of RemoteCommand
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? data = freezed,}) {
|
||||
return _then(_RemoteCommand(
|
||||
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteCommandType,data: freezed == data ? _self._data : data // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,21 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'remote_command.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_RemoteCommand _$RemoteCommandFromJson(Map<String, dynamic> json) =>
|
||||
_RemoteCommand(
|
||||
type: const _RemoteCommandTypeConverter().fromJson(
|
||||
(json['t'] as num).toInt(),
|
||||
),
|
||||
data: json['d'] as Map<String, dynamic>?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$RemoteCommandToJson(_RemoteCommand instance) =>
|
||||
<String, dynamic>{
|
||||
't': const _RemoteCommandTypeConverter().toJson(instance.type),
|
||||
'd': instance.data,
|
||||
};
|
||||
@@ -1,100 +1,35 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'remote_session.g.dart';
|
||||
part 'remote_session.freezed.dart';
|
||||
|
||||
enum RemoteSessionRole { host, remote }
|
||||
|
||||
enum RemoteSessionStatus { disconnected, connecting, connected, reconnecting, error }
|
||||
|
||||
@JsonSerializable()
|
||||
class RemoteDevice {
|
||||
final String id;
|
||||
final String name;
|
||||
final String platform;
|
||||
final DateTime connectedAt;
|
||||
final Map<String, bool> capabilities;
|
||||
|
||||
RemoteDevice({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.platform,
|
||||
DateTime? connectedAt,
|
||||
Map<String, bool>? capabilities,
|
||||
}) : connectedAt = connectedAt ?? DateTime.now(),
|
||||
capabilities = capabilities ?? {};
|
||||
|
||||
factory RemoteDevice.fromJson(Map<String, dynamic> json) => _$RemoteDeviceFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$RemoteDeviceToJson(this);
|
||||
|
||||
RemoteDevice copyWith({
|
||||
String? id,
|
||||
String? name,
|
||||
String? platform,
|
||||
DateTime? connectedAt,
|
||||
Map<String, bool>? capabilities,
|
||||
}) {
|
||||
return RemoteDevice(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
platform: platform ?? this.platform,
|
||||
connectedAt: connectedAt ?? this.connectedAt,
|
||||
capabilities: capabilities ?? this.capabilities,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is RemoteDevice && other.id == id;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
@freezed
|
||||
sealed class RemoteDevice with _$RemoteDevice {
|
||||
const factory RemoteDevice({
|
||||
required String id,
|
||||
required String name,
|
||||
required String platform,
|
||||
required DateTime connectedAt,
|
||||
@Default(<String, bool>{}) Map<String, bool> capabilities,
|
||||
}) = _RemoteDevice;
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class RemoteSession {
|
||||
@JsonKey(unknownEnumValue: RemoteSessionRole.remote)
|
||||
final RemoteSessionRole role;
|
||||
@JsonKey(unknownEnumValue: RemoteSessionStatus.disconnected)
|
||||
final RemoteSessionStatus status;
|
||||
final RemoteDevice? connectedDevice;
|
||||
final DateTime createdAt;
|
||||
final String? errorMessage;
|
||||
@freezed
|
||||
sealed class RemoteSession with _$RemoteSession {
|
||||
const RemoteSession._();
|
||||
|
||||
RemoteSession({
|
||||
required this.role,
|
||||
this.status = RemoteSessionStatus.disconnected,
|
||||
this.connectedDevice,
|
||||
DateTime? createdAt,
|
||||
this.errorMessage,
|
||||
}) : createdAt = createdAt ?? DateTime.now();
|
||||
const factory RemoteSession({
|
||||
required RemoteSessionRole role,
|
||||
@Default(RemoteSessionStatus.disconnected) RemoteSessionStatus status,
|
||||
RemoteDevice? connectedDevice,
|
||||
required DateTime createdAt,
|
||||
String? errorMessage,
|
||||
}) = _RemoteSession;
|
||||
|
||||
bool get isConnected => status == RemoteSessionStatus.connected;
|
||||
bool get isHost => role == RemoteSessionRole.host;
|
||||
bool get isRemote => role == RemoteSessionRole.remote;
|
||||
|
||||
factory RemoteSession.fromJson(Map<String, dynamic> json) => _$RemoteSessionFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$RemoteSessionToJson(this);
|
||||
|
||||
RemoteSession copyWith({
|
||||
RemoteSessionRole? role,
|
||||
RemoteSessionStatus? status,
|
||||
RemoteDevice? connectedDevice,
|
||||
bool clearConnectedDevice = false,
|
||||
DateTime? createdAt,
|
||||
String? errorMessage,
|
||||
bool clearErrorMessage = false,
|
||||
}) {
|
||||
return RemoteSession(
|
||||
role: role ?? this.role,
|
||||
status: status ?? this.status,
|
||||
connectedDevice: clearConnectedDevice ? null : (connectedDevice ?? this.connectedDevice),
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
errorMessage: clearErrorMessage ? null : (errorMessage ?? this.errorMessage),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,570 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'remote_session.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$RemoteDevice {
|
||||
|
||||
String get id; String get name; String get platform; DateTime get connectedAt; Map<String, bool> get capabilities;
|
||||
/// Create a copy of RemoteDevice
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$RemoteDeviceCopyWith<RemoteDevice> get copyWith => _$RemoteDeviceCopyWithImpl<RemoteDevice>(this as RemoteDevice, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is RemoteDevice&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.platform, platform) || other.platform == platform)&&(identical(other.connectedAt, connectedAt) || other.connectedAt == connectedAt)&&const DeepCollectionEquality().equals(other.capabilities, capabilities));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,platform,connectedAt,const DeepCollectionEquality().hash(capabilities));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RemoteDevice(id: $id, name: $name, platform: $platform, connectedAt: $connectedAt, capabilities: $capabilities)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $RemoteDeviceCopyWith<$Res> {
|
||||
factory $RemoteDeviceCopyWith(RemoteDevice value, $Res Function(RemoteDevice) _then) = _$RemoteDeviceCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String name, String platform, DateTime connectedAt, Map<String, bool> capabilities
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$RemoteDeviceCopyWithImpl<$Res>
|
||||
implements $RemoteDeviceCopyWith<$Res> {
|
||||
_$RemoteDeviceCopyWithImpl(this._self, this._then);
|
||||
|
||||
final RemoteDevice _self;
|
||||
final $Res Function(RemoteDevice) _then;
|
||||
|
||||
/// Create a copy of RemoteDevice
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? platform = null,Object? connectedAt = null,Object? capabilities = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,platform: null == platform ? _self.platform : platform // ignore: cast_nullable_to_non_nullable
|
||||
as String,connectedAt: null == connectedAt ? _self.connectedAt : connectedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,capabilities: null == capabilities ? _self.capabilities : capabilities // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, bool>,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [RemoteDevice].
|
||||
extension RemoteDevicePatterns on RemoteDevice {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _RemoteDevice value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteDevice() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _RemoteDevice value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteDevice():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _RemoteDevice value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteDevice() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String platform, DateTime connectedAt, Map<String, bool> capabilities)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteDevice() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.platform,_that.connectedAt,_that.capabilities);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String platform, DateTime connectedAt, Map<String, bool> capabilities) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteDevice():
|
||||
return $default(_that.id,_that.name,_that.platform,_that.connectedAt,_that.capabilities);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String platform, DateTime connectedAt, Map<String, bool> capabilities)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteDevice() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.platform,_that.connectedAt,_that.capabilities);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _RemoteDevice implements RemoteDevice {
|
||||
const _RemoteDevice({required this.id, required this.name, required this.platform, required this.connectedAt, final Map<String, bool> capabilities = const <String, bool>{}}): _capabilities = capabilities;
|
||||
|
||||
|
||||
@override final String id;
|
||||
@override final String name;
|
||||
@override final String platform;
|
||||
@override final DateTime connectedAt;
|
||||
final Map<String, bool> _capabilities;
|
||||
@override@JsonKey() Map<String, bool> get capabilities {
|
||||
if (_capabilities is EqualUnmodifiableMapView) return _capabilities;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(_capabilities);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of RemoteDevice
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$RemoteDeviceCopyWith<_RemoteDevice> get copyWith => __$RemoteDeviceCopyWithImpl<_RemoteDevice>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RemoteDevice&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.platform, platform) || other.platform == platform)&&(identical(other.connectedAt, connectedAt) || other.connectedAt == connectedAt)&&const DeepCollectionEquality().equals(other._capabilities, _capabilities));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,platform,connectedAt,const DeepCollectionEquality().hash(_capabilities));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RemoteDevice(id: $id, name: $name, platform: $platform, connectedAt: $connectedAt, capabilities: $capabilities)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$RemoteDeviceCopyWith<$Res> implements $RemoteDeviceCopyWith<$Res> {
|
||||
factory _$RemoteDeviceCopyWith(_RemoteDevice value, $Res Function(_RemoteDevice) _then) = __$RemoteDeviceCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String name, String platform, DateTime connectedAt, Map<String, bool> capabilities
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$RemoteDeviceCopyWithImpl<$Res>
|
||||
implements _$RemoteDeviceCopyWith<$Res> {
|
||||
__$RemoteDeviceCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _RemoteDevice _self;
|
||||
final $Res Function(_RemoteDevice) _then;
|
||||
|
||||
/// Create a copy of RemoteDevice
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? platform = null,Object? connectedAt = null,Object? capabilities = null,}) {
|
||||
return _then(_RemoteDevice(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,platform: null == platform ? _self.platform : platform // ignore: cast_nullable_to_non_nullable
|
||||
as String,connectedAt: null == connectedAt ? _self.connectedAt : connectedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,capabilities: null == capabilities ? _self._capabilities : capabilities // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, bool>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$RemoteSession {
|
||||
|
||||
RemoteSessionRole get role; RemoteSessionStatus get status; RemoteDevice? get connectedDevice; DateTime get createdAt; String? get errorMessage;
|
||||
/// Create a copy of RemoteSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$RemoteSessionCopyWith<RemoteSession> get copyWith => _$RemoteSessionCopyWithImpl<RemoteSession>(this as RemoteSession, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is RemoteSession&&(identical(other.role, role) || other.role == role)&&(identical(other.status, status) || other.status == status)&&(identical(other.connectedDevice, connectedDevice) || other.connectedDevice == connectedDevice)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,role,status,connectedDevice,createdAt,errorMessage);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RemoteSession(role: $role, status: $status, connectedDevice: $connectedDevice, createdAt: $createdAt, errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $RemoteSessionCopyWith<$Res> {
|
||||
factory $RemoteSessionCopyWith(RemoteSession value, $Res Function(RemoteSession) _then) = _$RemoteSessionCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
RemoteSessionRole role, RemoteSessionStatus status, RemoteDevice? connectedDevice, DateTime createdAt, String? errorMessage
|
||||
});
|
||||
|
||||
|
||||
$RemoteDeviceCopyWith<$Res>? get connectedDevice;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$RemoteSessionCopyWithImpl<$Res>
|
||||
implements $RemoteSessionCopyWith<$Res> {
|
||||
_$RemoteSessionCopyWithImpl(this._self, this._then);
|
||||
|
||||
final RemoteSession _self;
|
||||
final $Res Function(RemoteSession) _then;
|
||||
|
||||
/// Create a copy of RemoteSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? role = null,Object? status = null,Object? connectedDevice = freezed,Object? createdAt = null,Object? errorMessage = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteSessionRole,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteSessionStatus,connectedDevice: freezed == connectedDevice ? _self.connectedDevice : connectedDevice // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteDevice?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
/// Create a copy of RemoteSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$RemoteDeviceCopyWith<$Res>? get connectedDevice {
|
||||
if (_self.connectedDevice == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $RemoteDeviceCopyWith<$Res>(_self.connectedDevice!, (value) {
|
||||
return _then(_self.copyWith(connectedDevice: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [RemoteSession].
|
||||
extension RemoteSessionPatterns on RemoteSession {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _RemoteSession value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteSession() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _RemoteSession value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteSession():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _RemoteSession value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteSession() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( RemoteSessionRole role, RemoteSessionStatus status, RemoteDevice? connectedDevice, DateTime createdAt, String? errorMessage)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteSession() when $default != null:
|
||||
return $default(_that.role,_that.status,_that.connectedDevice,_that.createdAt,_that.errorMessage);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( RemoteSessionRole role, RemoteSessionStatus status, RemoteDevice? connectedDevice, DateTime createdAt, String? errorMessage) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteSession():
|
||||
return $default(_that.role,_that.status,_that.connectedDevice,_that.createdAt,_that.errorMessage);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( RemoteSessionRole role, RemoteSessionStatus status, RemoteDevice? connectedDevice, DateTime createdAt, String? errorMessage)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _RemoteSession() when $default != null:
|
||||
return $default(_that.role,_that.status,_that.connectedDevice,_that.createdAt,_that.errorMessage);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _RemoteSession extends RemoteSession {
|
||||
const _RemoteSession({required this.role, this.status = RemoteSessionStatus.disconnected, this.connectedDevice, required this.createdAt, this.errorMessage}): super._();
|
||||
|
||||
|
||||
@override final RemoteSessionRole role;
|
||||
@override@JsonKey() final RemoteSessionStatus status;
|
||||
@override final RemoteDevice? connectedDevice;
|
||||
@override final DateTime createdAt;
|
||||
@override final String? errorMessage;
|
||||
|
||||
/// Create a copy of RemoteSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$RemoteSessionCopyWith<_RemoteSession> get copyWith => __$RemoteSessionCopyWithImpl<_RemoteSession>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RemoteSession&&(identical(other.role, role) || other.role == role)&&(identical(other.status, status) || other.status == status)&&(identical(other.connectedDevice, connectedDevice) || other.connectedDevice == connectedDevice)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,role,status,connectedDevice,createdAt,errorMessage);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RemoteSession(role: $role, status: $status, connectedDevice: $connectedDevice, createdAt: $createdAt, errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$RemoteSessionCopyWith<$Res> implements $RemoteSessionCopyWith<$Res> {
|
||||
factory _$RemoteSessionCopyWith(_RemoteSession value, $Res Function(_RemoteSession) _then) = __$RemoteSessionCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
RemoteSessionRole role, RemoteSessionStatus status, RemoteDevice? connectedDevice, DateTime createdAt, String? errorMessage
|
||||
});
|
||||
|
||||
|
||||
@override $RemoteDeviceCopyWith<$Res>? get connectedDevice;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$RemoteSessionCopyWithImpl<$Res>
|
||||
implements _$RemoteSessionCopyWith<$Res> {
|
||||
__$RemoteSessionCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _RemoteSession _self;
|
||||
final $Res Function(_RemoteSession) _then;
|
||||
|
||||
/// Create a copy of RemoteSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? role = null,Object? status = null,Object? connectedDevice = freezed,Object? createdAt = null,Object? errorMessage = freezed,}) {
|
||||
return _then(_RemoteSession(
|
||||
role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteSessionRole,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteSessionStatus,connectedDevice: freezed == connectedDevice ? _self.connectedDevice : connectedDevice // ignore: cast_nullable_to_non_nullable
|
||||
as RemoteDevice?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of RemoteSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$RemoteDeviceCopyWith<$Res>? get connectedDevice {
|
||||
if (_self.connectedDevice == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $RemoteDeviceCopyWith<$Res>(_self.connectedDevice!, (value) {
|
||||
return _then(_self.copyWith(connectedDevice: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,75 +0,0 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'remote_session.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
RemoteDevice _$RemoteDeviceFromJson(Map<String, dynamic> json) => RemoteDevice(
|
||||
id: json['id'] as String,
|
||||
name: json['name'] as String,
|
||||
platform: json['platform'] as String,
|
||||
connectedAt: json['connectedAt'] == null
|
||||
? null
|
||||
: DateTime.parse(json['connectedAt'] as String),
|
||||
capabilities: (json['capabilities'] as Map<String, dynamic>?)?.map(
|
||||
(k, e) => MapEntry(k, e as bool),
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$RemoteDeviceToJson(RemoteDevice instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'platform': instance.platform,
|
||||
'connectedAt': instance.connectedAt.toIso8601String(),
|
||||
'capabilities': instance.capabilities,
|
||||
};
|
||||
|
||||
RemoteSession _$RemoteSessionFromJson(Map<String, dynamic> json) =>
|
||||
RemoteSession(
|
||||
role: $enumDecode(
|
||||
_$RemoteSessionRoleEnumMap,
|
||||
json['role'],
|
||||
unknownValue: RemoteSessionRole.remote,
|
||||
),
|
||||
status:
|
||||
$enumDecodeNullable(
|
||||
_$RemoteSessionStatusEnumMap,
|
||||
json['status'],
|
||||
unknownValue: RemoteSessionStatus.disconnected,
|
||||
) ??
|
||||
RemoteSessionStatus.disconnected,
|
||||
connectedDevice: json['connectedDevice'] == null
|
||||
? null
|
||||
: RemoteDevice.fromJson(
|
||||
json['connectedDevice'] as Map<String, dynamic>,
|
||||
),
|
||||
createdAt: json['createdAt'] == null
|
||||
? null
|
||||
: DateTime.parse(json['createdAt'] as String),
|
||||
errorMessage: json['errorMessage'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$RemoteSessionToJson(RemoteSession instance) =>
|
||||
<String, dynamic>{
|
||||
'role': _$RemoteSessionRoleEnumMap[instance.role]!,
|
||||
'status': _$RemoteSessionStatusEnumMap[instance.status]!,
|
||||
'connectedDevice': instance.connectedDevice,
|
||||
'createdAt': instance.createdAt.toIso8601String(),
|
||||
'errorMessage': instance.errorMessage,
|
||||
};
|
||||
|
||||
const _$RemoteSessionRoleEnumMap = {
|
||||
RemoteSessionRole.host: 'host',
|
||||
RemoteSessionRole.remote: 'remote',
|
||||
};
|
||||
|
||||
const _$RemoteSessionStatusEnumMap = {
|
||||
RemoteSessionStatus.disconnected: 'disconnected',
|
||||
RemoteSessionStatus.connecting: 'connecting',
|
||||
RemoteSessionStatus.connected: 'connected',
|
||||
RemoteSessionStatus.reconnecting: 'reconnecting',
|
||||
RemoteSessionStatus.error: 'error',
|
||||
};
|
||||
@@ -1,5 +1,10 @@
|
||||
// ignore_for_file: invalid_annotation_target
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../utils/formatters.dart';
|
||||
|
||||
part 'download_models.freezed.dart';
|
||||
|
||||
enum DownloadStatus {
|
||||
queued,
|
||||
downloading,
|
||||
@@ -10,30 +15,21 @@ enum DownloadStatus {
|
||||
partial, // Some episodes downloaded, but not all (for shows/seasons)
|
||||
}
|
||||
|
||||
class DownloadProgress {
|
||||
final String globalKey;
|
||||
final DownloadStatus status;
|
||||
final int progress; // 0-100
|
||||
final int downloadedBytes;
|
||||
final int totalBytes;
|
||||
final double speed; // bytes per second
|
||||
final String? errorMessage;
|
||||
final String? currentFile; // What's being downloaded (video, subtitles, artwork)
|
||||
@freezed
|
||||
sealed class DownloadProgress with _$DownloadProgress {
|
||||
const DownloadProgress._();
|
||||
|
||||
// Thumbnail path (populated after artwork download completes)
|
||||
final String? thumbPath;
|
||||
|
||||
const DownloadProgress({
|
||||
required this.globalKey,
|
||||
required this.status,
|
||||
this.progress = 0,
|
||||
this.downloadedBytes = 0,
|
||||
this.totalBytes = 0,
|
||||
this.speed = 0,
|
||||
this.errorMessage,
|
||||
this.currentFile,
|
||||
this.thumbPath,
|
||||
});
|
||||
const factory DownloadProgress({
|
||||
required String globalKey,
|
||||
required DownloadStatus status,
|
||||
@Default(0) int progress,
|
||||
@Default(0) int downloadedBytes,
|
||||
@Default(0) int totalBytes,
|
||||
@Default(0.0) double speed,
|
||||
String? errorMessage,
|
||||
String? currentFile,
|
||||
String? thumbPath,
|
||||
}) = _DownloadProgress;
|
||||
|
||||
double get progressPercent => progress / 100.0;
|
||||
|
||||
@@ -42,73 +38,23 @@ class DownloadProgress {
|
||||
String get totalFormatted => ByteFormatter.formatBytes(totalBytes);
|
||||
|
||||
bool get hasArtworkPaths => thumbPath != null;
|
||||
|
||||
DownloadProgress copyWith({
|
||||
String? globalKey,
|
||||
DownloadStatus? status,
|
||||
int? progress,
|
||||
int? downloadedBytes,
|
||||
int? totalBytes,
|
||||
double? speed,
|
||||
String? errorMessage,
|
||||
String? currentFile,
|
||||
String? thumbPath,
|
||||
}) {
|
||||
return DownloadProgress(
|
||||
globalKey: globalKey ?? this.globalKey,
|
||||
status: status ?? this.status,
|
||||
progress: progress ?? this.progress,
|
||||
downloadedBytes: downloadedBytes ?? this.downloadedBytes,
|
||||
totalBytes: totalBytes ?? this.totalBytes,
|
||||
speed: speed ?? this.speed,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
currentFile: currentFile ?? this.currentFile,
|
||||
thumbPath: thumbPath ?? this.thumbPath,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DeletionProgress {
|
||||
final String globalKey;
|
||||
final String itemTitle;
|
||||
final int currentItem;
|
||||
final int totalItems;
|
||||
final String? currentOperation;
|
||||
@freezed
|
||||
sealed class DeletionProgress with _$DeletionProgress {
|
||||
const DeletionProgress._();
|
||||
|
||||
const DeletionProgress({
|
||||
required this.globalKey,
|
||||
required this.itemTitle,
|
||||
required this.currentItem,
|
||||
required this.totalItems,
|
||||
this.currentOperation,
|
||||
});
|
||||
const factory DeletionProgress({
|
||||
required String globalKey,
|
||||
required String itemTitle,
|
||||
required int currentItem,
|
||||
required int totalItems,
|
||||
String? currentOperation,
|
||||
}) = _DeletionProgress;
|
||||
|
||||
double get progressPercent => totalItems > 0 ? (currentItem / totalItems) : 0.0;
|
||||
|
||||
int get progressPercentInt => (progressPercent * 100).round();
|
||||
|
||||
bool get isComplete => currentItem >= totalItems;
|
||||
|
||||
DeletionProgress copyWith({
|
||||
String? globalKey,
|
||||
String? itemTitle,
|
||||
int? currentItem,
|
||||
int? totalItems,
|
||||
String? currentOperation,
|
||||
}) {
|
||||
return DeletionProgress(
|
||||
globalKey: globalKey ?? this.globalKey,
|
||||
itemTitle: itemTitle ?? this.itemTitle,
|
||||
currentItem: currentItem ?? this.currentItem,
|
||||
totalItems: totalItems ?? this.totalItems,
|
||||
currentOperation: currentOperation ?? this.currentOperation,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeletionProgress(globalKey: $globalKey, itemTitle: $itemTitle, '
|
||||
'currentItem: $currentItem, totalItems: $totalItems, '
|
||||
'progressPercent: $progressPercentInt%)';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,552 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'download_models.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DownloadProgress {
|
||||
|
||||
String get globalKey; DownloadStatus get status; int get progress; int get downloadedBytes; int get totalBytes; double get speed; String? get errorMessage; String? get currentFile; String? get thumbPath;
|
||||
/// Create a copy of DownloadProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DownloadProgressCopyWith<DownloadProgress> get copyWith => _$DownloadProgressCopyWithImpl<DownloadProgress>(this as DownloadProgress, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DownloadProgress&&(identical(other.globalKey, globalKey) || other.globalKey == globalKey)&&(identical(other.status, status) || other.status == status)&&(identical(other.progress, progress) || other.progress == progress)&&(identical(other.downloadedBytes, downloadedBytes) || other.downloadedBytes == downloadedBytes)&&(identical(other.totalBytes, totalBytes) || other.totalBytes == totalBytes)&&(identical(other.speed, speed) || other.speed == speed)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.currentFile, currentFile) || other.currentFile == currentFile)&&(identical(other.thumbPath, thumbPath) || other.thumbPath == thumbPath));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,globalKey,status,progress,downloadedBytes,totalBytes,speed,errorMessage,currentFile,thumbPath);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DownloadProgress(globalKey: $globalKey, status: $status, progress: $progress, downloadedBytes: $downloadedBytes, totalBytes: $totalBytes, speed: $speed, errorMessage: $errorMessage, currentFile: $currentFile, thumbPath: $thumbPath)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DownloadProgressCopyWith<$Res> {
|
||||
factory $DownloadProgressCopyWith(DownloadProgress value, $Res Function(DownloadProgress) _then) = _$DownloadProgressCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String globalKey, DownloadStatus status, int progress, int downloadedBytes, int totalBytes, double speed, String? errorMessage, String? currentFile, String? thumbPath
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DownloadProgressCopyWithImpl<$Res>
|
||||
implements $DownloadProgressCopyWith<$Res> {
|
||||
_$DownloadProgressCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DownloadProgress _self;
|
||||
final $Res Function(DownloadProgress) _then;
|
||||
|
||||
/// Create a copy of DownloadProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? globalKey = null,Object? status = null,Object? progress = null,Object? downloadedBytes = null,Object? totalBytes = null,Object? speed = null,Object? errorMessage = freezed,Object? currentFile = freezed,Object? thumbPath = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
globalKey: null == globalKey ? _self.globalKey : globalKey // ignore: cast_nullable_to_non_nullable
|
||||
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||
as DownloadStatus,progress: null == progress ? _self.progress : progress // ignore: cast_nullable_to_non_nullable
|
||||
as int,downloadedBytes: null == downloadedBytes ? _self.downloadedBytes : downloadedBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int,totalBytes: null == totalBytes ? _self.totalBytes : totalBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int,speed: null == speed ? _self.speed : speed // ignore: cast_nullable_to_non_nullable
|
||||
as double,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,currentFile: freezed == currentFile ? _self.currentFile : currentFile // ignore: cast_nullable_to_non_nullable
|
||||
as String?,thumbPath: freezed == thumbPath ? _self.thumbPath : thumbPath // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DownloadProgress].
|
||||
extension DownloadProgressPatterns on DownloadProgress {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DownloadProgress value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DownloadProgress() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DownloadProgress value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DownloadProgress():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DownloadProgress value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DownloadProgress() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String globalKey, DownloadStatus status, int progress, int downloadedBytes, int totalBytes, double speed, String? errorMessage, String? currentFile, String? thumbPath)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DownloadProgress() when $default != null:
|
||||
return $default(_that.globalKey,_that.status,_that.progress,_that.downloadedBytes,_that.totalBytes,_that.speed,_that.errorMessage,_that.currentFile,_that.thumbPath);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String globalKey, DownloadStatus status, int progress, int downloadedBytes, int totalBytes, double speed, String? errorMessage, String? currentFile, String? thumbPath) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DownloadProgress():
|
||||
return $default(_that.globalKey,_that.status,_that.progress,_that.downloadedBytes,_that.totalBytes,_that.speed,_that.errorMessage,_that.currentFile,_that.thumbPath);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String globalKey, DownloadStatus status, int progress, int downloadedBytes, int totalBytes, double speed, String? errorMessage, String? currentFile, String? thumbPath)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DownloadProgress() when $default != null:
|
||||
return $default(_that.globalKey,_that.status,_that.progress,_that.downloadedBytes,_that.totalBytes,_that.speed,_that.errorMessage,_that.currentFile,_that.thumbPath);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DownloadProgress extends DownloadProgress {
|
||||
const _DownloadProgress({required this.globalKey, required this.status, this.progress = 0, this.downloadedBytes = 0, this.totalBytes = 0, this.speed = 0.0, this.errorMessage, this.currentFile, this.thumbPath}): super._();
|
||||
|
||||
|
||||
@override final String globalKey;
|
||||
@override final DownloadStatus status;
|
||||
@override@JsonKey() final int progress;
|
||||
@override@JsonKey() final int downloadedBytes;
|
||||
@override@JsonKey() final int totalBytes;
|
||||
@override@JsonKey() final double speed;
|
||||
@override final String? errorMessage;
|
||||
@override final String? currentFile;
|
||||
@override final String? thumbPath;
|
||||
|
||||
/// Create a copy of DownloadProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DownloadProgressCopyWith<_DownloadProgress> get copyWith => __$DownloadProgressCopyWithImpl<_DownloadProgress>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DownloadProgress&&(identical(other.globalKey, globalKey) || other.globalKey == globalKey)&&(identical(other.status, status) || other.status == status)&&(identical(other.progress, progress) || other.progress == progress)&&(identical(other.downloadedBytes, downloadedBytes) || other.downloadedBytes == downloadedBytes)&&(identical(other.totalBytes, totalBytes) || other.totalBytes == totalBytes)&&(identical(other.speed, speed) || other.speed == speed)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.currentFile, currentFile) || other.currentFile == currentFile)&&(identical(other.thumbPath, thumbPath) || other.thumbPath == thumbPath));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,globalKey,status,progress,downloadedBytes,totalBytes,speed,errorMessage,currentFile,thumbPath);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DownloadProgress(globalKey: $globalKey, status: $status, progress: $progress, downloadedBytes: $downloadedBytes, totalBytes: $totalBytes, speed: $speed, errorMessage: $errorMessage, currentFile: $currentFile, thumbPath: $thumbPath)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DownloadProgressCopyWith<$Res> implements $DownloadProgressCopyWith<$Res> {
|
||||
factory _$DownloadProgressCopyWith(_DownloadProgress value, $Res Function(_DownloadProgress) _then) = __$DownloadProgressCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String globalKey, DownloadStatus status, int progress, int downloadedBytes, int totalBytes, double speed, String? errorMessage, String? currentFile, String? thumbPath
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DownloadProgressCopyWithImpl<$Res>
|
||||
implements _$DownloadProgressCopyWith<$Res> {
|
||||
__$DownloadProgressCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DownloadProgress _self;
|
||||
final $Res Function(_DownloadProgress) _then;
|
||||
|
||||
/// Create a copy of DownloadProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? globalKey = null,Object? status = null,Object? progress = null,Object? downloadedBytes = null,Object? totalBytes = null,Object? speed = null,Object? errorMessage = freezed,Object? currentFile = freezed,Object? thumbPath = freezed,}) {
|
||||
return _then(_DownloadProgress(
|
||||
globalKey: null == globalKey ? _self.globalKey : globalKey // ignore: cast_nullable_to_non_nullable
|
||||
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
|
||||
as DownloadStatus,progress: null == progress ? _self.progress : progress // ignore: cast_nullable_to_non_nullable
|
||||
as int,downloadedBytes: null == downloadedBytes ? _self.downloadedBytes : downloadedBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int,totalBytes: null == totalBytes ? _self.totalBytes : totalBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int,speed: null == speed ? _self.speed : speed // ignore: cast_nullable_to_non_nullable
|
||||
as double,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,currentFile: freezed == currentFile ? _self.currentFile : currentFile // ignore: cast_nullable_to_non_nullable
|
||||
as String?,thumbPath: freezed == thumbPath ? _self.thumbPath : thumbPath // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$DeletionProgress {
|
||||
|
||||
String get globalKey; String get itemTitle; int get currentItem; int get totalItems; String? get currentOperation;
|
||||
/// Create a copy of DeletionProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DeletionProgressCopyWith<DeletionProgress> get copyWith => _$DeletionProgressCopyWithImpl<DeletionProgress>(this as DeletionProgress, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeletionProgress&&(identical(other.globalKey, globalKey) || other.globalKey == globalKey)&&(identical(other.itemTitle, itemTitle) || other.itemTitle == itemTitle)&&(identical(other.currentItem, currentItem) || other.currentItem == currentItem)&&(identical(other.totalItems, totalItems) || other.totalItems == totalItems)&&(identical(other.currentOperation, currentOperation) || other.currentOperation == currentOperation));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,globalKey,itemTitle,currentItem,totalItems,currentOperation);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeletionProgress(globalKey: $globalKey, itemTitle: $itemTitle, currentItem: $currentItem, totalItems: $totalItems, currentOperation: $currentOperation)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DeletionProgressCopyWith<$Res> {
|
||||
factory $DeletionProgressCopyWith(DeletionProgress value, $Res Function(DeletionProgress) _then) = _$DeletionProgressCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String globalKey, String itemTitle, int currentItem, int totalItems, String? currentOperation
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DeletionProgressCopyWithImpl<$Res>
|
||||
implements $DeletionProgressCopyWith<$Res> {
|
||||
_$DeletionProgressCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DeletionProgress _self;
|
||||
final $Res Function(DeletionProgress) _then;
|
||||
|
||||
/// Create a copy of DeletionProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? globalKey = null,Object? itemTitle = null,Object? currentItem = null,Object? totalItems = null,Object? currentOperation = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
globalKey: null == globalKey ? _self.globalKey : globalKey // ignore: cast_nullable_to_non_nullable
|
||||
as String,itemTitle: null == itemTitle ? _self.itemTitle : itemTitle // ignore: cast_nullable_to_non_nullable
|
||||
as String,currentItem: null == currentItem ? _self.currentItem : currentItem // ignore: cast_nullable_to_non_nullable
|
||||
as int,totalItems: null == totalItems ? _self.totalItems : totalItems // ignore: cast_nullable_to_non_nullable
|
||||
as int,currentOperation: freezed == currentOperation ? _self.currentOperation : currentOperation // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DeletionProgress].
|
||||
extension DeletionProgressPatterns on DeletionProgress {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DeletionProgress value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeletionProgress() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DeletionProgress value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeletionProgress():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DeletionProgress value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeletionProgress() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String globalKey, String itemTitle, int currentItem, int totalItems, String? currentOperation)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeletionProgress() when $default != null:
|
||||
return $default(_that.globalKey,_that.itemTitle,_that.currentItem,_that.totalItems,_that.currentOperation);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String globalKey, String itemTitle, int currentItem, int totalItems, String? currentOperation) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeletionProgress():
|
||||
return $default(_that.globalKey,_that.itemTitle,_that.currentItem,_that.totalItems,_that.currentOperation);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String globalKey, String itemTitle, int currentItem, int totalItems, String? currentOperation)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeletionProgress() when $default != null:
|
||||
return $default(_that.globalKey,_that.itemTitle,_that.currentItem,_that.totalItems,_that.currentOperation);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DeletionProgress extends DeletionProgress {
|
||||
const _DeletionProgress({required this.globalKey, required this.itemTitle, required this.currentItem, required this.totalItems, this.currentOperation}): super._();
|
||||
|
||||
|
||||
@override final String globalKey;
|
||||
@override final String itemTitle;
|
||||
@override final int currentItem;
|
||||
@override final int totalItems;
|
||||
@override final String? currentOperation;
|
||||
|
||||
/// Create a copy of DeletionProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DeletionProgressCopyWith<_DeletionProgress> get copyWith => __$DeletionProgressCopyWithImpl<_DeletionProgress>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeletionProgress&&(identical(other.globalKey, globalKey) || other.globalKey == globalKey)&&(identical(other.itemTitle, itemTitle) || other.itemTitle == itemTitle)&&(identical(other.currentItem, currentItem) || other.currentItem == currentItem)&&(identical(other.totalItems, totalItems) || other.totalItems == totalItems)&&(identical(other.currentOperation, currentOperation) || other.currentOperation == currentOperation));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,globalKey,itemTitle,currentItem,totalItems,currentOperation);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeletionProgress(globalKey: $globalKey, itemTitle: $itemTitle, currentItem: $currentItem, totalItems: $totalItems, currentOperation: $currentOperation)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DeletionProgressCopyWith<$Res> implements $DeletionProgressCopyWith<$Res> {
|
||||
factory _$DeletionProgressCopyWith(_DeletionProgress value, $Res Function(_DeletionProgress) _then) = __$DeletionProgressCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String globalKey, String itemTitle, int currentItem, int totalItems, String? currentOperation
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DeletionProgressCopyWithImpl<$Res>
|
||||
implements _$DeletionProgressCopyWith<$Res> {
|
||||
__$DeletionProgressCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DeletionProgress _self;
|
||||
final $Res Function(_DeletionProgress) _then;
|
||||
|
||||
/// Create a copy of DeletionProgress
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? globalKey = null,Object? itemTitle = null,Object? currentItem = null,Object? totalItems = null,Object? currentOperation = freezed,}) {
|
||||
return _then(_DeletionProgress(
|
||||
globalKey: null == globalKey ? _self.globalKey : globalKey // ignore: cast_nullable_to_non_nullable
|
||||
as String,itemTitle: null == itemTitle ? _self.itemTitle : itemTitle // ignore: cast_nullable_to_non_nullable
|
||||
as String,currentItem: null == currentItem ? _self.currentItem : currentItem // ignore: cast_nullable_to_non_nullable
|
||||
as int,totalItems: null == totalItems ? _self.totalItems : totalItems // ignore: cast_nullable_to_non_nullable
|
||||
as int,currentOperation: freezed == currentOperation ? _self.currentOperation : currentOperation // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -27,5 +27,5 @@ Map<String, dynamic> _$PlexHomeToJson(PlexHome instance) => <String, dynamic>{
|
||||
'guestUserUUID': instance.guestUserUUID,
|
||||
'guestEnabled': instance.guestEnabled,
|
||||
'subscription': instance.subscription,
|
||||
'users': instance.users,
|
||||
'users': instance.users.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
// ignore_for_file: invalid_annotation_target
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'shader_preset.freezed.dart';
|
||||
part 'shader_preset.g.dart';
|
||||
|
||||
enum ShaderPresetType { none, nvscaler, artcnn, anime4k, custom }
|
||||
|
||||
/// ArtCNN real-time model sizes.
|
||||
@@ -51,76 +57,34 @@ enum Anime4KMode {
|
||||
modeCA,
|
||||
}
|
||||
|
||||
class Anime4KConfig {
|
||||
final Anime4KQuality quality;
|
||||
final Anime4KMode mode;
|
||||
@freezed
|
||||
sealed class Anime4KConfig with _$Anime4KConfig {
|
||||
const factory Anime4KConfig({
|
||||
@JsonKey(unknownEnumValue: Anime4KQuality.fast) required Anime4KQuality quality,
|
||||
@JsonKey(unknownEnumValue: Anime4KMode.modeA) required Anime4KMode mode,
|
||||
}) = _Anime4KConfig;
|
||||
|
||||
const Anime4KConfig({required this.quality, required this.mode});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
return other is Anime4KConfig && other.quality == quality && other.mode == mode;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => quality.hashCode ^ mode.hashCode;
|
||||
|
||||
Map<String, dynamic> toJson() => {'quality': quality.name, 'mode': mode.name};
|
||||
|
||||
factory Anime4KConfig.fromJson(Map<String, dynamic> json) {
|
||||
return Anime4KConfig(
|
||||
quality: Anime4KQuality.values.asNameMap()[json['quality']] ?? Anime4KQuality.fast,
|
||||
mode: Anime4KMode.values.asNameMap()[json['mode']] ?? Anime4KMode.modeA,
|
||||
);
|
||||
}
|
||||
factory Anime4KConfig.fromJson(Map<String, dynamic> json) => _$Anime4KConfigFromJson(json);
|
||||
}
|
||||
|
||||
class ArtCNNConfig {
|
||||
final ArtCNNModel model;
|
||||
final ArtCNNVariant variant;
|
||||
@freezed
|
||||
sealed class ArtCNNConfig with _$ArtCNNConfig {
|
||||
const factory ArtCNNConfig({
|
||||
@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) required ArtCNNModel model,
|
||||
@JsonKey(unknownEnumValue: ArtCNNVariant.neutral) required ArtCNNVariant variant,
|
||||
}) = _ArtCNNConfig;
|
||||
|
||||
const ArtCNNConfig({required this.model, required this.variant});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
return other is ArtCNNConfig && other.model == model && other.variant == variant;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => model.hashCode ^ variant.hashCode;
|
||||
|
||||
Map<String, dynamic> toJson() => {'model': model.name, 'variant': variant.name};
|
||||
|
||||
factory ArtCNNConfig.fromJson(Map<String, dynamic> json) {
|
||||
return ArtCNNConfig(
|
||||
model: ArtCNNModel.values.asNameMap()[json['model']] ?? ArtCNNModel.c4f16,
|
||||
variant: ArtCNNVariant.values.asNameMap()[json['variant']] ?? ArtCNNVariant.neutral,
|
||||
);
|
||||
}
|
||||
factory ArtCNNConfig.fromJson(Map<String, dynamic> json) => _$ArtCNNConfigFromJson(json);
|
||||
}
|
||||
|
||||
class NVScalerConfig {
|
||||
@freezed
|
||||
sealed class NVScalerConfig with _$NVScalerConfig {
|
||||
const factory NVScalerConfig({
|
||||
/// Whether to automatically skip NVScaler on HDR content
|
||||
final bool autoHdrSkip;
|
||||
@Default(true) bool autoHdrSkip,
|
||||
}) = _NVScalerConfig;
|
||||
|
||||
const NVScalerConfig({this.autoHdrSkip = true});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
return other is NVScalerConfig && other.autoHdrSkip == autoHdrSkip;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => autoHdrSkip.hashCode;
|
||||
|
||||
Map<String, dynamic> toJson() => {'autoHdrSkip': autoHdrSkip};
|
||||
|
||||
factory NVScalerConfig.fromJson(Map<String, dynamic> json) {
|
||||
return NVScalerConfig(autoHdrSkip: json['autoHdrSkip'] as bool? ?? true);
|
||||
}
|
||||
factory NVScalerConfig.fromJson(Map<String, dynamic> json) => _$NVScalerConfigFromJson(json);
|
||||
}
|
||||
|
||||
class ShaderPreset {
|
||||
|
||||
@@ -0,0 +1,793 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'shader_preset.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$Anime4KConfig {
|
||||
|
||||
@JsonKey(unknownEnumValue: Anime4KQuality.fast) Anime4KQuality get quality;@JsonKey(unknownEnumValue: Anime4KMode.modeA) Anime4KMode get mode;
|
||||
/// Create a copy of Anime4KConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$Anime4KConfigCopyWith<Anime4KConfig> get copyWith => _$Anime4KConfigCopyWithImpl<Anime4KConfig>(this as Anime4KConfig, _$identity);
|
||||
|
||||
/// Serializes this Anime4KConfig to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is Anime4KConfig&&(identical(other.quality, quality) || other.quality == quality)&&(identical(other.mode, mode) || other.mode == mode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,quality,mode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Anime4KConfig(quality: $quality, mode: $mode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $Anime4KConfigCopyWith<$Res> {
|
||||
factory $Anime4KConfigCopyWith(Anime4KConfig value, $Res Function(Anime4KConfig) _then) = _$Anime4KConfigCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
@JsonKey(unknownEnumValue: Anime4KQuality.fast) Anime4KQuality quality,@JsonKey(unknownEnumValue: Anime4KMode.modeA) Anime4KMode mode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$Anime4KConfigCopyWithImpl<$Res>
|
||||
implements $Anime4KConfigCopyWith<$Res> {
|
||||
_$Anime4KConfigCopyWithImpl(this._self, this._then);
|
||||
|
||||
final Anime4KConfig _self;
|
||||
final $Res Function(Anime4KConfig) _then;
|
||||
|
||||
/// Create a copy of Anime4KConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? quality = null,Object? mode = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
quality: null == quality ? _self.quality : quality // ignore: cast_nullable_to_non_nullable
|
||||
as Anime4KQuality,mode: null == mode ? _self.mode : mode // ignore: cast_nullable_to_non_nullable
|
||||
as Anime4KMode,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [Anime4KConfig].
|
||||
extension Anime4KConfigPatterns on Anime4KConfig {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _Anime4KConfig value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime4KConfig() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _Anime4KConfig value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime4KConfig():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _Anime4KConfig value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime4KConfig() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function(@JsonKey(unknownEnumValue: Anime4KQuality.fast) Anime4KQuality quality, @JsonKey(unknownEnumValue: Anime4KMode.modeA) Anime4KMode mode)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime4KConfig() when $default != null:
|
||||
return $default(_that.quality,_that.mode);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function(@JsonKey(unknownEnumValue: Anime4KQuality.fast) Anime4KQuality quality, @JsonKey(unknownEnumValue: Anime4KMode.modeA) Anime4KMode mode) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime4KConfig():
|
||||
return $default(_that.quality,_that.mode);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function(@JsonKey(unknownEnumValue: Anime4KQuality.fast) Anime4KQuality quality, @JsonKey(unknownEnumValue: Anime4KMode.modeA) Anime4KMode mode)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime4KConfig() when $default != null:
|
||||
return $default(_that.quality,_that.mode);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _Anime4KConfig implements Anime4KConfig {
|
||||
const _Anime4KConfig({@JsonKey(unknownEnumValue: Anime4KQuality.fast) required this.quality, @JsonKey(unknownEnumValue: Anime4KMode.modeA) required this.mode});
|
||||
factory _Anime4KConfig.fromJson(Map<String, dynamic> json) => _$Anime4KConfigFromJson(json);
|
||||
|
||||
@override@JsonKey(unknownEnumValue: Anime4KQuality.fast) final Anime4KQuality quality;
|
||||
@override@JsonKey(unknownEnumValue: Anime4KMode.modeA) final Anime4KMode mode;
|
||||
|
||||
/// Create a copy of Anime4KConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$Anime4KConfigCopyWith<_Anime4KConfig> get copyWith => __$Anime4KConfigCopyWithImpl<_Anime4KConfig>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$Anime4KConfigToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Anime4KConfig&&(identical(other.quality, quality) || other.quality == quality)&&(identical(other.mode, mode) || other.mode == mode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,quality,mode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Anime4KConfig(quality: $quality, mode: $mode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$Anime4KConfigCopyWith<$Res> implements $Anime4KConfigCopyWith<$Res> {
|
||||
factory _$Anime4KConfigCopyWith(_Anime4KConfig value, $Res Function(_Anime4KConfig) _then) = __$Anime4KConfigCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
@JsonKey(unknownEnumValue: Anime4KQuality.fast) Anime4KQuality quality,@JsonKey(unknownEnumValue: Anime4KMode.modeA) Anime4KMode mode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$Anime4KConfigCopyWithImpl<$Res>
|
||||
implements _$Anime4KConfigCopyWith<$Res> {
|
||||
__$Anime4KConfigCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Anime4KConfig _self;
|
||||
final $Res Function(_Anime4KConfig) _then;
|
||||
|
||||
/// Create a copy of Anime4KConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? quality = null,Object? mode = null,}) {
|
||||
return _then(_Anime4KConfig(
|
||||
quality: null == quality ? _self.quality : quality // ignore: cast_nullable_to_non_nullable
|
||||
as Anime4KQuality,mode: null == mode ? _self.mode : mode // ignore: cast_nullable_to_non_nullable
|
||||
as Anime4KMode,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ArtCNNConfig {
|
||||
|
||||
@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) ArtCNNModel get model;@JsonKey(unknownEnumValue: ArtCNNVariant.neutral) ArtCNNVariant get variant;
|
||||
/// Create a copy of ArtCNNConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ArtCNNConfigCopyWith<ArtCNNConfig> get copyWith => _$ArtCNNConfigCopyWithImpl<ArtCNNConfig>(this as ArtCNNConfig, _$identity);
|
||||
|
||||
/// Serializes this ArtCNNConfig to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ArtCNNConfig&&(identical(other.model, model) || other.model == model)&&(identical(other.variant, variant) || other.variant == variant));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,model,variant);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ArtCNNConfig(model: $model, variant: $variant)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ArtCNNConfigCopyWith<$Res> {
|
||||
factory $ArtCNNConfigCopyWith(ArtCNNConfig value, $Res Function(ArtCNNConfig) _then) = _$ArtCNNConfigCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) ArtCNNModel model,@JsonKey(unknownEnumValue: ArtCNNVariant.neutral) ArtCNNVariant variant
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ArtCNNConfigCopyWithImpl<$Res>
|
||||
implements $ArtCNNConfigCopyWith<$Res> {
|
||||
_$ArtCNNConfigCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ArtCNNConfig _self;
|
||||
final $Res Function(ArtCNNConfig) _then;
|
||||
|
||||
/// Create a copy of ArtCNNConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? model = null,Object? variant = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
model: null == model ? _self.model : model // ignore: cast_nullable_to_non_nullable
|
||||
as ArtCNNModel,variant: null == variant ? _self.variant : variant // ignore: cast_nullable_to_non_nullable
|
||||
as ArtCNNVariant,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ArtCNNConfig].
|
||||
extension ArtCNNConfigPatterns on ArtCNNConfig {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ArtCNNConfig value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ArtCNNConfig() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ArtCNNConfig value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ArtCNNConfig():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ArtCNNConfig value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ArtCNNConfig() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function(@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) ArtCNNModel model, @JsonKey(unknownEnumValue: ArtCNNVariant.neutral) ArtCNNVariant variant)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ArtCNNConfig() when $default != null:
|
||||
return $default(_that.model,_that.variant);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function(@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) ArtCNNModel model, @JsonKey(unknownEnumValue: ArtCNNVariant.neutral) ArtCNNVariant variant) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ArtCNNConfig():
|
||||
return $default(_that.model,_that.variant);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function(@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) ArtCNNModel model, @JsonKey(unknownEnumValue: ArtCNNVariant.neutral) ArtCNNVariant variant)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ArtCNNConfig() when $default != null:
|
||||
return $default(_that.model,_that.variant);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _ArtCNNConfig implements ArtCNNConfig {
|
||||
const _ArtCNNConfig({@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) required this.model, @JsonKey(unknownEnumValue: ArtCNNVariant.neutral) required this.variant});
|
||||
factory _ArtCNNConfig.fromJson(Map<String, dynamic> json) => _$ArtCNNConfigFromJson(json);
|
||||
|
||||
@override@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) final ArtCNNModel model;
|
||||
@override@JsonKey(unknownEnumValue: ArtCNNVariant.neutral) final ArtCNNVariant variant;
|
||||
|
||||
/// Create a copy of ArtCNNConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ArtCNNConfigCopyWith<_ArtCNNConfig> get copyWith => __$ArtCNNConfigCopyWithImpl<_ArtCNNConfig>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$ArtCNNConfigToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ArtCNNConfig&&(identical(other.model, model) || other.model == model)&&(identical(other.variant, variant) || other.variant == variant));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,model,variant);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ArtCNNConfig(model: $model, variant: $variant)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ArtCNNConfigCopyWith<$Res> implements $ArtCNNConfigCopyWith<$Res> {
|
||||
factory _$ArtCNNConfigCopyWith(_ArtCNNConfig value, $Res Function(_ArtCNNConfig) _then) = __$ArtCNNConfigCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
@JsonKey(unknownEnumValue: ArtCNNModel.c4f16) ArtCNNModel model,@JsonKey(unknownEnumValue: ArtCNNVariant.neutral) ArtCNNVariant variant
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ArtCNNConfigCopyWithImpl<$Res>
|
||||
implements _$ArtCNNConfigCopyWith<$Res> {
|
||||
__$ArtCNNConfigCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ArtCNNConfig _self;
|
||||
final $Res Function(_ArtCNNConfig) _then;
|
||||
|
||||
/// Create a copy of ArtCNNConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? model = null,Object? variant = null,}) {
|
||||
return _then(_ArtCNNConfig(
|
||||
model: null == model ? _self.model : model // ignore: cast_nullable_to_non_nullable
|
||||
as ArtCNNModel,variant: null == variant ? _self.variant : variant // ignore: cast_nullable_to_non_nullable
|
||||
as ArtCNNVariant,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$NVScalerConfig {
|
||||
|
||||
/// Whether to automatically skip NVScaler on HDR content
|
||||
bool get autoHdrSkip;
|
||||
/// Create a copy of NVScalerConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$NVScalerConfigCopyWith<NVScalerConfig> get copyWith => _$NVScalerConfigCopyWithImpl<NVScalerConfig>(this as NVScalerConfig, _$identity);
|
||||
|
||||
/// Serializes this NVScalerConfig to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is NVScalerConfig&&(identical(other.autoHdrSkip, autoHdrSkip) || other.autoHdrSkip == autoHdrSkip));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,autoHdrSkip);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NVScalerConfig(autoHdrSkip: $autoHdrSkip)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $NVScalerConfigCopyWith<$Res> {
|
||||
factory $NVScalerConfigCopyWith(NVScalerConfig value, $Res Function(NVScalerConfig) _then) = _$NVScalerConfigCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool autoHdrSkip
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$NVScalerConfigCopyWithImpl<$Res>
|
||||
implements $NVScalerConfigCopyWith<$Res> {
|
||||
_$NVScalerConfigCopyWithImpl(this._self, this._then);
|
||||
|
||||
final NVScalerConfig _self;
|
||||
final $Res Function(NVScalerConfig) _then;
|
||||
|
||||
/// Create a copy of NVScalerConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? autoHdrSkip = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
autoHdrSkip: null == autoHdrSkip ? _self.autoHdrSkip : autoHdrSkip // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [NVScalerConfig].
|
||||
extension NVScalerConfigPatterns on NVScalerConfig {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _NVScalerConfig value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _NVScalerConfig() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _NVScalerConfig value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _NVScalerConfig():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _NVScalerConfig value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _NVScalerConfig() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool autoHdrSkip)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _NVScalerConfig() when $default != null:
|
||||
return $default(_that.autoHdrSkip);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool autoHdrSkip) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _NVScalerConfig():
|
||||
return $default(_that.autoHdrSkip);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool autoHdrSkip)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _NVScalerConfig() when $default != null:
|
||||
return $default(_that.autoHdrSkip);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _NVScalerConfig implements NVScalerConfig {
|
||||
const _NVScalerConfig({this.autoHdrSkip = true});
|
||||
factory _NVScalerConfig.fromJson(Map<String, dynamic> json) => _$NVScalerConfigFromJson(json);
|
||||
|
||||
/// Whether to automatically skip NVScaler on HDR content
|
||||
@override@JsonKey() final bool autoHdrSkip;
|
||||
|
||||
/// Create a copy of NVScalerConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$NVScalerConfigCopyWith<_NVScalerConfig> get copyWith => __$NVScalerConfigCopyWithImpl<_NVScalerConfig>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$NVScalerConfigToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _NVScalerConfig&&(identical(other.autoHdrSkip, autoHdrSkip) || other.autoHdrSkip == autoHdrSkip));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,autoHdrSkip);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'NVScalerConfig(autoHdrSkip: $autoHdrSkip)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$NVScalerConfigCopyWith<$Res> implements $NVScalerConfigCopyWith<$Res> {
|
||||
factory _$NVScalerConfigCopyWith(_NVScalerConfig value, $Res Function(_NVScalerConfig) _then) = __$NVScalerConfigCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool autoHdrSkip
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$NVScalerConfigCopyWithImpl<$Res>
|
||||
implements _$NVScalerConfigCopyWith<$Res> {
|
||||
__$NVScalerConfigCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _NVScalerConfig _self;
|
||||
final $Res Function(_NVScalerConfig) _then;
|
||||
|
||||
/// Create a copy of NVScalerConfig
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? autoHdrSkip = null,}) {
|
||||
return _then(_NVScalerConfig(
|
||||
autoHdrSkip: null == autoHdrSkip ? _self.autoHdrSkip : autoHdrSkip // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,78 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'shader_preset.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_Anime4KConfig _$Anime4KConfigFromJson(Map<String, dynamic> json) =>
|
||||
_Anime4KConfig(
|
||||
quality: $enumDecode(
|
||||
_$Anime4KQualityEnumMap,
|
||||
json['quality'],
|
||||
unknownValue: Anime4KQuality.fast,
|
||||
),
|
||||
mode: $enumDecode(
|
||||
_$Anime4KModeEnumMap,
|
||||
json['mode'],
|
||||
unknownValue: Anime4KMode.modeA,
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$Anime4KConfigToJson(_Anime4KConfig instance) =>
|
||||
<String, dynamic>{
|
||||
'quality': _$Anime4KQualityEnumMap[instance.quality]!,
|
||||
'mode': _$Anime4KModeEnumMap[instance.mode]!,
|
||||
};
|
||||
|
||||
const _$Anime4KQualityEnumMap = {
|
||||
Anime4KQuality.fast: 'fast',
|
||||
Anime4KQuality.hq: 'hq',
|
||||
};
|
||||
|
||||
const _$Anime4KModeEnumMap = {
|
||||
Anime4KMode.modeA: 'modeA',
|
||||
Anime4KMode.modeB: 'modeB',
|
||||
Anime4KMode.modeC: 'modeC',
|
||||
Anime4KMode.modeAA: 'modeAA',
|
||||
Anime4KMode.modeBB: 'modeBB',
|
||||
Anime4KMode.modeCA: 'modeCA',
|
||||
};
|
||||
|
||||
_ArtCNNConfig _$ArtCNNConfigFromJson(Map<String, dynamic> json) =>
|
||||
_ArtCNNConfig(
|
||||
model: $enumDecode(
|
||||
_$ArtCNNModelEnumMap,
|
||||
json['model'],
|
||||
unknownValue: ArtCNNModel.c4f16,
|
||||
),
|
||||
variant: $enumDecode(
|
||||
_$ArtCNNVariantEnumMap,
|
||||
json['variant'],
|
||||
unknownValue: ArtCNNVariant.neutral,
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ArtCNNConfigToJson(_ArtCNNConfig instance) =>
|
||||
<String, dynamic>{
|
||||
'model': _$ArtCNNModelEnumMap[instance.model]!,
|
||||
'variant': _$ArtCNNVariantEnumMap[instance.variant]!,
|
||||
};
|
||||
|
||||
const _$ArtCNNModelEnumMap = {
|
||||
ArtCNNModel.c4f16: 'c4f16',
|
||||
ArtCNNModel.c4f32: 'c4f32',
|
||||
};
|
||||
|
||||
const _$ArtCNNVariantEnumMap = {
|
||||
ArtCNNVariant.neutral: 'neutral',
|
||||
ArtCNNVariant.denoise: 'denoise',
|
||||
ArtCNNVariant.denoiseSharpen: 'denoiseSharpen',
|
||||
};
|
||||
|
||||
_NVScalerConfig _$NVScalerConfigFromJson(Map<String, dynamic> json) =>
|
||||
_NVScalerConfig(autoHdrSkip: json['autoHdrSkip'] as bool? ?? true);
|
||||
|
||||
Map<String, dynamic> _$NVScalerConfigToJson(_NVScalerConfig instance) =>
|
||||
<String, dynamic>{'autoHdrSkip': instance.autoHdrSkip};
|
||||
@@ -1,52 +1,33 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'device_code.freezed.dart';
|
||||
|
||||
/// Result of requesting a device code from an RFC 8628 authorization server.
|
||||
///
|
||||
/// The user enters [userCode] at [verificationUrl]; the app polls the token
|
||||
/// endpoint with [deviceCode] every [interval] seconds until [expiresIn]
|
||||
/// seconds elapse.
|
||||
class DeviceCode {
|
||||
final String deviceCode;
|
||||
final String userCode;
|
||||
final String verificationUrl;
|
||||
@freezed
|
||||
sealed class DeviceCode with _$DeviceCode {
|
||||
const factory DeviceCode({
|
||||
required String deviceCode,
|
||||
required String userCode,
|
||||
required String verificationUrl,
|
||||
required int expiresIn,
|
||||
required int interval,
|
||||
|
||||
/// URL with the code pre-filled (e.g. `https://trakt.tv/activate/ABC12345`)
|
||||
/// when the provider supports it. Nullable — Simkl doesn't.
|
||||
final String? verificationUrlComplete;
|
||||
|
||||
final int expiresIn;
|
||||
final int interval;
|
||||
|
||||
const DeviceCode({
|
||||
required this.deviceCode,
|
||||
required this.userCode,
|
||||
required this.verificationUrl,
|
||||
required this.expiresIn,
|
||||
required this.interval,
|
||||
this.verificationUrlComplete,
|
||||
});
|
||||
String? verificationUrlComplete,
|
||||
}) = _DeviceCode;
|
||||
}
|
||||
|
||||
/// Discriminated event emitted by a device-code poll loop.
|
||||
sealed class DevicePollEvent {
|
||||
const DevicePollEvent();
|
||||
}
|
||||
|
||||
class DevicePollPending extends DevicePollEvent {
|
||||
const DevicePollPending();
|
||||
}
|
||||
|
||||
class DevicePollSlowDown extends DevicePollEvent {
|
||||
const DevicePollSlowDown();
|
||||
}
|
||||
|
||||
class DevicePollDenied extends DevicePollEvent {
|
||||
const DevicePollDenied();
|
||||
}
|
||||
|
||||
class DevicePollExpired extends DevicePollEvent {
|
||||
const DevicePollExpired();
|
||||
}
|
||||
|
||||
class DevicePollSuccess extends DevicePollEvent {
|
||||
final Map<String, dynamic> tokenResponse;
|
||||
const DevicePollSuccess(this.tokenResponse);
|
||||
@freezed
|
||||
sealed class DevicePollEvent with _$DevicePollEvent {
|
||||
const factory DevicePollEvent.pending() = DevicePollPending;
|
||||
const factory DevicePollEvent.slowDown() = DevicePollSlowDown;
|
||||
const factory DevicePollEvent.denied() = DevicePollDenied;
|
||||
const factory DevicePollEvent.expired() = DevicePollExpired;
|
||||
const factory DevicePollEvent.success(Map<String, dynamic> tokenResponse) = DevicePollSuccess;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,718 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'device_code.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$DeviceCode {
|
||||
|
||||
String get deviceCode; String get userCode; String get verificationUrl; int get expiresIn; int get interval;/// URL with the code pre-filled (e.g. `https://trakt.tv/activate/ABC12345`)
|
||||
/// when the provider supports it. Nullable — Simkl doesn't.
|
||||
String? get verificationUrlComplete;
|
||||
/// Create a copy of DeviceCode
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DeviceCodeCopyWith<DeviceCode> get copyWith => _$DeviceCodeCopyWithImpl<DeviceCode>(this as DeviceCode, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DeviceCode&&(identical(other.deviceCode, deviceCode) || other.deviceCode == deviceCode)&&(identical(other.userCode, userCode) || other.userCode == userCode)&&(identical(other.verificationUrl, verificationUrl) || other.verificationUrl == verificationUrl)&&(identical(other.expiresIn, expiresIn) || other.expiresIn == expiresIn)&&(identical(other.interval, interval) || other.interval == interval)&&(identical(other.verificationUrlComplete, verificationUrlComplete) || other.verificationUrlComplete == verificationUrlComplete));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,deviceCode,userCode,verificationUrl,expiresIn,interval,verificationUrlComplete);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeviceCode(deviceCode: $deviceCode, userCode: $userCode, verificationUrl: $verificationUrl, expiresIn: $expiresIn, interval: $interval, verificationUrlComplete: $verificationUrlComplete)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DeviceCodeCopyWith<$Res> {
|
||||
factory $DeviceCodeCopyWith(DeviceCode value, $Res Function(DeviceCode) _then) = _$DeviceCodeCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String deviceCode, String userCode, String verificationUrl, int expiresIn, int interval, String? verificationUrlComplete
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DeviceCodeCopyWithImpl<$Res>
|
||||
implements $DeviceCodeCopyWith<$Res> {
|
||||
_$DeviceCodeCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DeviceCode _self;
|
||||
final $Res Function(DeviceCode) _then;
|
||||
|
||||
/// Create a copy of DeviceCode
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? deviceCode = null,Object? userCode = null,Object? verificationUrl = null,Object? expiresIn = null,Object? interval = null,Object? verificationUrlComplete = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
deviceCode: null == deviceCode ? _self.deviceCode : deviceCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,userCode: null == userCode ? _self.userCode : userCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,verificationUrl: null == verificationUrl ? _self.verificationUrl : verificationUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,expiresIn: null == expiresIn ? _self.expiresIn : expiresIn // ignore: cast_nullable_to_non_nullable
|
||||
as int,interval: null == interval ? _self.interval : interval // ignore: cast_nullable_to_non_nullable
|
||||
as int,verificationUrlComplete: freezed == verificationUrlComplete ? _self.verificationUrlComplete : verificationUrlComplete // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DeviceCode].
|
||||
extension DeviceCodePatterns on DeviceCode {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _DeviceCode value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceCode() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _DeviceCode value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceCode():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _DeviceCode value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceCode() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String deviceCode, String userCode, String verificationUrl, int expiresIn, int interval, String? verificationUrlComplete)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceCode() when $default != null:
|
||||
return $default(_that.deviceCode,_that.userCode,_that.verificationUrl,_that.expiresIn,_that.interval,_that.verificationUrlComplete);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String deviceCode, String userCode, String verificationUrl, int expiresIn, int interval, String? verificationUrlComplete) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceCode():
|
||||
return $default(_that.deviceCode,_that.userCode,_that.verificationUrl,_that.expiresIn,_that.interval,_that.verificationUrlComplete);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String deviceCode, String userCode, String verificationUrl, int expiresIn, int interval, String? verificationUrlComplete)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _DeviceCode() when $default != null:
|
||||
return $default(_that.deviceCode,_that.userCode,_that.verificationUrl,_that.expiresIn,_that.interval,_that.verificationUrlComplete);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _DeviceCode implements DeviceCode {
|
||||
const _DeviceCode({required this.deviceCode, required this.userCode, required this.verificationUrl, required this.expiresIn, required this.interval, this.verificationUrlComplete});
|
||||
|
||||
|
||||
@override final String deviceCode;
|
||||
@override final String userCode;
|
||||
@override final String verificationUrl;
|
||||
@override final int expiresIn;
|
||||
@override final int interval;
|
||||
/// URL with the code pre-filled (e.g. `https://trakt.tv/activate/ABC12345`)
|
||||
/// when the provider supports it. Nullable — Simkl doesn't.
|
||||
@override final String? verificationUrlComplete;
|
||||
|
||||
/// Create a copy of DeviceCode
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$DeviceCodeCopyWith<_DeviceCode> get copyWith => __$DeviceCodeCopyWithImpl<_DeviceCode>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DeviceCode&&(identical(other.deviceCode, deviceCode) || other.deviceCode == deviceCode)&&(identical(other.userCode, userCode) || other.userCode == userCode)&&(identical(other.verificationUrl, verificationUrl) || other.verificationUrl == verificationUrl)&&(identical(other.expiresIn, expiresIn) || other.expiresIn == expiresIn)&&(identical(other.interval, interval) || other.interval == interval)&&(identical(other.verificationUrlComplete, verificationUrlComplete) || other.verificationUrlComplete == verificationUrlComplete));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,deviceCode,userCode,verificationUrl,expiresIn,interval,verificationUrlComplete);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DeviceCode(deviceCode: $deviceCode, userCode: $userCode, verificationUrl: $verificationUrl, expiresIn: $expiresIn, interval: $interval, verificationUrlComplete: $verificationUrlComplete)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$DeviceCodeCopyWith<$Res> implements $DeviceCodeCopyWith<$Res> {
|
||||
factory _$DeviceCodeCopyWith(_DeviceCode value, $Res Function(_DeviceCode) _then) = __$DeviceCodeCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String deviceCode, String userCode, String verificationUrl, int expiresIn, int interval, String? verificationUrlComplete
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$DeviceCodeCopyWithImpl<$Res>
|
||||
implements _$DeviceCodeCopyWith<$Res> {
|
||||
__$DeviceCodeCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _DeviceCode _self;
|
||||
final $Res Function(_DeviceCode) _then;
|
||||
|
||||
/// Create a copy of DeviceCode
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? deviceCode = null,Object? userCode = null,Object? verificationUrl = null,Object? expiresIn = null,Object? interval = null,Object? verificationUrlComplete = freezed,}) {
|
||||
return _then(_DeviceCode(
|
||||
deviceCode: null == deviceCode ? _self.deviceCode : deviceCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,userCode: null == userCode ? _self.userCode : userCode // ignore: cast_nullable_to_non_nullable
|
||||
as String,verificationUrl: null == verificationUrl ? _self.verificationUrl : verificationUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,expiresIn: null == expiresIn ? _self.expiresIn : expiresIn // ignore: cast_nullable_to_non_nullable
|
||||
as int,interval: null == interval ? _self.interval : interval // ignore: cast_nullable_to_non_nullable
|
||||
as int,verificationUrlComplete: freezed == verificationUrlComplete ? _self.verificationUrlComplete : verificationUrlComplete // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$DevicePollEvent {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DevicePollEvent);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DevicePollEvent()';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class $DevicePollEventCopyWith<$Res> {
|
||||
$DevicePollEventCopyWith(DevicePollEvent _, $Res Function(DevicePollEvent) __);
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [DevicePollEvent].
|
||||
extension DevicePollEventPatterns on DevicePollEvent {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( DevicePollPending value)? pending,TResult Function( DevicePollSlowDown value)? slowDown,TResult Function( DevicePollDenied value)? denied,TResult Function( DevicePollExpired value)? expired,TResult Function( DevicePollSuccess value)? success,required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case DevicePollPending() when pending != null:
|
||||
return pending(_that);case DevicePollSlowDown() when slowDown != null:
|
||||
return slowDown(_that);case DevicePollDenied() when denied != null:
|
||||
return denied(_that);case DevicePollExpired() when expired != null:
|
||||
return expired(_that);case DevicePollSuccess() when success != null:
|
||||
return success(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( DevicePollPending value) pending,required TResult Function( DevicePollSlowDown value) slowDown,required TResult Function( DevicePollDenied value) denied,required TResult Function( DevicePollExpired value) expired,required TResult Function( DevicePollSuccess value) success,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case DevicePollPending():
|
||||
return pending(_that);case DevicePollSlowDown():
|
||||
return slowDown(_that);case DevicePollDenied():
|
||||
return denied(_that);case DevicePollExpired():
|
||||
return expired(_that);case DevicePollSuccess():
|
||||
return success(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( DevicePollPending value)? pending,TResult? Function( DevicePollSlowDown value)? slowDown,TResult? Function( DevicePollDenied value)? denied,TResult? Function( DevicePollExpired value)? expired,TResult? Function( DevicePollSuccess value)? success,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case DevicePollPending() when pending != null:
|
||||
return pending(_that);case DevicePollSlowDown() when slowDown != null:
|
||||
return slowDown(_that);case DevicePollDenied() when denied != null:
|
||||
return denied(_that);case DevicePollExpired() when expired != null:
|
||||
return expired(_that);case DevicePollSuccess() when success != null:
|
||||
return success(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? pending,TResult Function()? slowDown,TResult Function()? denied,TResult Function()? expired,TResult Function( Map<String, dynamic> tokenResponse)? success,required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case DevicePollPending() when pending != null:
|
||||
return pending();case DevicePollSlowDown() when slowDown != null:
|
||||
return slowDown();case DevicePollDenied() when denied != null:
|
||||
return denied();case DevicePollExpired() when expired != null:
|
||||
return expired();case DevicePollSuccess() when success != null:
|
||||
return success(_that.tokenResponse);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() pending,required TResult Function() slowDown,required TResult Function() denied,required TResult Function() expired,required TResult Function( Map<String, dynamic> tokenResponse) success,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case DevicePollPending():
|
||||
return pending();case DevicePollSlowDown():
|
||||
return slowDown();case DevicePollDenied():
|
||||
return denied();case DevicePollExpired():
|
||||
return expired();case DevicePollSuccess():
|
||||
return success(_that.tokenResponse);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? pending,TResult? Function()? slowDown,TResult? Function()? denied,TResult? Function()? expired,TResult? Function( Map<String, dynamic> tokenResponse)? success,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case DevicePollPending() when pending != null:
|
||||
return pending();case DevicePollSlowDown() when slowDown != null:
|
||||
return slowDown();case DevicePollDenied() when denied != null:
|
||||
return denied();case DevicePollExpired() when expired != null:
|
||||
return expired();case DevicePollSuccess() when success != null:
|
||||
return success(_that.tokenResponse);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class DevicePollPending implements DevicePollEvent {
|
||||
const DevicePollPending();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DevicePollPending);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DevicePollEvent.pending()';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class $DevicePollPendingCopyWith<$Res> implements $DevicePollEventCopyWith<$Res> {
|
||||
$DevicePollPendingCopyWith(DevicePollPending _, $Res Function(DevicePollPending) __);
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DevicePollPendingCopyWithImpl<$Res>
|
||||
implements $DevicePollPendingCopyWith<$Res> {
|
||||
_$DevicePollPendingCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DevicePollPending _self;
|
||||
final $Res Function(DevicePollPending) _then;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class DevicePollSlowDown implements DevicePollEvent {
|
||||
const DevicePollSlowDown();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DevicePollSlowDown);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DevicePollEvent.slowDown()';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class $DevicePollSlowDownCopyWith<$Res> implements $DevicePollEventCopyWith<$Res> {
|
||||
$DevicePollSlowDownCopyWith(DevicePollSlowDown _, $Res Function(DevicePollSlowDown) __);
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DevicePollSlowDownCopyWithImpl<$Res>
|
||||
implements $DevicePollSlowDownCopyWith<$Res> {
|
||||
_$DevicePollSlowDownCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DevicePollSlowDown _self;
|
||||
final $Res Function(DevicePollSlowDown) _then;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class DevicePollDenied implements DevicePollEvent {
|
||||
const DevicePollDenied();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DevicePollDenied);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DevicePollEvent.denied()';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class $DevicePollDeniedCopyWith<$Res> implements $DevicePollEventCopyWith<$Res> {
|
||||
$DevicePollDeniedCopyWith(DevicePollDenied _, $Res Function(DevicePollDenied) __);
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DevicePollDeniedCopyWithImpl<$Res>
|
||||
implements $DevicePollDeniedCopyWith<$Res> {
|
||||
_$DevicePollDeniedCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DevicePollDenied _self;
|
||||
final $Res Function(DevicePollDenied) _then;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class DevicePollExpired implements DevicePollEvent {
|
||||
const DevicePollExpired();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DevicePollExpired);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DevicePollEvent.expired()';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class $DevicePollExpiredCopyWith<$Res> implements $DevicePollEventCopyWith<$Res> {
|
||||
$DevicePollExpiredCopyWith(DevicePollExpired _, $Res Function(DevicePollExpired) __);
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DevicePollExpiredCopyWithImpl<$Res>
|
||||
implements $DevicePollExpiredCopyWith<$Res> {
|
||||
_$DevicePollExpiredCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DevicePollExpired _self;
|
||||
final $Res Function(DevicePollExpired) _then;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class DevicePollSuccess implements DevicePollEvent {
|
||||
const DevicePollSuccess(final Map<String, dynamic> tokenResponse): _tokenResponse = tokenResponse;
|
||||
|
||||
|
||||
final Map<String, dynamic> _tokenResponse;
|
||||
Map<String, dynamic> get tokenResponse {
|
||||
if (_tokenResponse is EqualUnmodifiableMapView) return _tokenResponse;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(_tokenResponse);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of DevicePollEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$DevicePollSuccessCopyWith<DevicePollSuccess> get copyWith => _$DevicePollSuccessCopyWithImpl<DevicePollSuccess>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is DevicePollSuccess&&const DeepCollectionEquality().equals(other._tokenResponse, _tokenResponse));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_tokenResponse));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DevicePollEvent.success(tokenResponse: $tokenResponse)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $DevicePollSuccessCopyWith<$Res> implements $DevicePollEventCopyWith<$Res> {
|
||||
factory $DevicePollSuccessCopyWith(DevicePollSuccess value, $Res Function(DevicePollSuccess) _then) = _$DevicePollSuccessCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
Map<String, dynamic> tokenResponse
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$DevicePollSuccessCopyWithImpl<$Res>
|
||||
implements $DevicePollSuccessCopyWith<$Res> {
|
||||
_$DevicePollSuccessCopyWithImpl(this._self, this._then);
|
||||
|
||||
final DevicePollSuccess _self;
|
||||
final $Res Function(DevicePollSuccess) _then;
|
||||
|
||||
/// Create a copy of DevicePollEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') $Res call({Object? tokenResponse = null,}) {
|
||||
return _then(DevicePollSuccess(
|
||||
null == tokenResponse ? _self._tokenResponse : tokenResponse // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,16 +1,42 @@
|
||||
// ignore_for_file: invalid_annotation_target
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../utils/json_utils.dart';
|
||||
|
||||
part 'fribb_mapping_row.g.dart';
|
||||
|
||||
Object? _readTvdbSeason(Map json, String key) {
|
||||
final season = json['season'];
|
||||
return season is Map ? season['tvdb'] : null;
|
||||
}
|
||||
|
||||
Object? _readTmdbSeason(Map json, String key) {
|
||||
final season = json['season'];
|
||||
return season is Map ? season['tmdb'] : null;
|
||||
}
|
||||
|
||||
/// One row from `anime-list-mini.json` (Fribb/anime-lists).
|
||||
@JsonSerializable(createToJson: false)
|
||||
class FribbMappingRow {
|
||||
@JsonKey(name: 'anilist_id', fromJson: flexibleInt)
|
||||
final int? anilistId;
|
||||
@JsonKey(name: 'imdb_id')
|
||||
final String? imdbId;
|
||||
@JsonKey(name: 'mal_id', fromJson: flexibleInt)
|
||||
final int? malId;
|
||||
@JsonKey(name: 'simkl_id', fromJson: flexibleInt)
|
||||
final int? simklId;
|
||||
@JsonKey(name: 'themoviedb_id', fromJson: flexibleInt)
|
||||
final int? tmdbId;
|
||||
@JsonKey(name: 'tvdb_id', fromJson: flexibleInt)
|
||||
final int? tvdbId;
|
||||
|
||||
/// Plex season number this mapping corresponds to. A single show-level
|
||||
/// external ID can resolve to multiple rows for split-cour anime; the
|
||||
/// resolver picks by matching the episode's `parentIndex` against these.
|
||||
@JsonKey(readValue: _readTvdbSeason, fromJson: flexibleInt)
|
||||
final int? tvdbSeason;
|
||||
@JsonKey(readValue: _readTmdbSeason, fromJson: flexibleInt)
|
||||
final int? tmdbSeason;
|
||||
|
||||
/// `TV` / `MOVIE` / `OVA` / `ONA` / `SPECIAL` / `UNKNOWN` / `null`.
|
||||
@@ -30,24 +56,5 @@ class FribbMappingRow {
|
||||
|
||||
bool get isMovie => type == 'MOVIE';
|
||||
|
||||
factory FribbMappingRow.fromJson(Map<String, dynamic> json) {
|
||||
final season = json['season'];
|
||||
int? tvdbSeason;
|
||||
int? tmdbSeason;
|
||||
if (season is Map) {
|
||||
tvdbSeason = (season['tvdb'] as num?)?.toInt();
|
||||
tmdbSeason = (season['tmdb'] as num?)?.toInt();
|
||||
}
|
||||
return FribbMappingRow(
|
||||
anilistId: (json['anilist_id'] as num?)?.toInt(),
|
||||
imdbId: json['imdb_id'] as String?,
|
||||
malId: (json['mal_id'] as num?)?.toInt(),
|
||||
simklId: (json['simkl_id'] as num?)?.toInt(),
|
||||
tmdbId: (json['themoviedb_id'] as num?)?.toInt(),
|
||||
tvdbId: (json['tvdb_id'] as num?)?.toInt(),
|
||||
tvdbSeason: tvdbSeason,
|
||||
tmdbSeason: tmdbSeason,
|
||||
type: json['type'] as String?,
|
||||
);
|
||||
}
|
||||
factory FribbMappingRow.fromJson(Map<String, dynamic> json) => _$FribbMappingRowFromJson(json);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'fribb_mapping_row.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
FribbMappingRow _$FribbMappingRowFromJson(Map<String, dynamic> json) =>
|
||||
FribbMappingRow(
|
||||
anilistId: flexibleInt(json['anilist_id']),
|
||||
imdbId: json['imdb_id'] as String?,
|
||||
malId: flexibleInt(json['mal_id']),
|
||||
simklId: flexibleInt(json['simkl_id']),
|
||||
tmdbId: flexibleInt(json['themoviedb_id']),
|
||||
tvdbId: flexibleInt(json['tvdb_id']),
|
||||
tvdbSeason: flexibleInt(_readTvdbSeason(json, 'tvdbSeason')),
|
||||
tmdbSeason: flexibleInt(_readTmdbSeason(json, 'tmdbSeason')),
|
||||
type: json['type'] as String?,
|
||||
);
|
||||
@@ -1,110 +1,94 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'trakt_ids.dart';
|
||||
|
||||
part 'trakt_scrobble_request.freezed.dart';
|
||||
|
||||
/// Body for `POST /scrobble/{start|pause|stop}` and `POST /sync/history`.
|
||||
///
|
||||
/// Either movie IDs or show IDs + season/episode are set, never both.
|
||||
/// [progress] is the percent (0–100) for scrobble; ignored for `/sync/history`.
|
||||
class TraktScrobbleRequest {
|
||||
final TraktIds? _movieIds;
|
||||
final TraktIds? _showIds;
|
||||
final int? _season;
|
||||
final int? _episode;
|
||||
final double? progress;
|
||||
|
||||
const TraktScrobbleRequest._({TraktIds? movieIds, TraktIds? showIds, int? season, int? episode, this.progress})
|
||||
: _movieIds = movieIds,
|
||||
_showIds = showIds,
|
||||
_season = season,
|
||||
_episode = episode;
|
||||
|
||||
bool get isMovie => _movieIds != null;
|
||||
bool get isEpisode => _showIds != null;
|
||||
|
||||
TraktScrobbleRequest copyWith({double? progress}) => TraktScrobbleRequest._(
|
||||
movieIds: _movieIds,
|
||||
showIds: _showIds,
|
||||
season: _season,
|
||||
episode: _episode,
|
||||
progress: progress ?? this.progress,
|
||||
);
|
||||
@freezed
|
||||
sealed class TraktScrobbleRequest with _$TraktScrobbleRequest {
|
||||
const TraktScrobbleRequest._();
|
||||
|
||||
/// Build a movie scrobble payload.
|
||||
factory TraktScrobbleRequest.movie({required TraktIds ids, double? progress}) {
|
||||
return TraktScrobbleRequest._(movieIds: ids, progress: progress);
|
||||
}
|
||||
const factory TraktScrobbleRequest.movie({required TraktIds ids, double? progress}) = TraktScrobbleMovieRequest;
|
||||
|
||||
/// Build an episode scrobble payload using the show's external IDs plus
|
||||
/// season/episode index. Trakt prefers this shape over an episode-IDs-only
|
||||
/// payload because it works even when the episode itself isn't in Trakt's
|
||||
/// catalog yet.
|
||||
factory TraktScrobbleRequest.episode({
|
||||
const factory TraktScrobbleRequest.episode({
|
||||
required TraktIds showIds,
|
||||
required int season,
|
||||
required int number,
|
||||
double? progress,
|
||||
}) {
|
||||
return TraktScrobbleRequest._(showIds: showIds, season: season, episode: number, progress: progress);
|
||||
}
|
||||
}) = TraktScrobbleEpisodeRequest;
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
if (_movieIds != null) 'movie': {'ids': _movieIds.toJson()},
|
||||
if (_showIds != null) 'show': {'ids': _showIds.toJson()},
|
||||
if (_season != null && _episode != null) 'episode': {'season': _season, 'number': _episode},
|
||||
bool get isMovie => this is TraktScrobbleMovieRequest;
|
||||
bool get isEpisode => this is TraktScrobbleEpisodeRequest;
|
||||
|
||||
Map<String, dynamic> toJson() => switch (this) {
|
||||
TraktScrobbleMovieRequest(:final ids, :final progress) => {
|
||||
'movie': {'ids': ids.toJson()},
|
||||
'progress': ?progress,
|
||||
},
|
||||
TraktScrobbleEpisodeRequest(:final showIds, :final season, :final number, :final progress) => {
|
||||
'show': {'ids': showIds.toJson()},
|
||||
'episode': {'season': season, 'number': number},
|
||||
'progress': ?progress,
|
||||
},
|
||||
};
|
||||
|
||||
/// Build a `POST /sync/history` body that adds this item to history.
|
||||
///
|
||||
/// Optional [watchedAt] (ISO-8601 UTC) lets the server attribute the play
|
||||
/// to a specific point in time; defaults to "now" on Trakt's side.
|
||||
Map<String, dynamic> toHistoryAddBody({String? watchedAt}) {
|
||||
if (isMovie) {
|
||||
return {
|
||||
Map<String, dynamic> toHistoryAddBody({String? watchedAt}) => switch (this) {
|
||||
TraktScrobbleMovieRequest(:final ids) => {
|
||||
'movies': [
|
||||
{'watched_at': ?watchedAt, 'ids': _movieIds!.toJson()},
|
||||
{'watched_at': ?watchedAt, 'ids': ids.toJson()},
|
||||
],
|
||||
};
|
||||
}
|
||||
return {
|
||||
},
|
||||
TraktScrobbleEpisodeRequest(:final showIds, :final season, :final number) => {
|
||||
'shows': [
|
||||
{
|
||||
'ids': _showIds!.toJson(),
|
||||
'ids': showIds.toJson(),
|
||||
'seasons': [
|
||||
{
|
||||
'number': _season,
|
||||
'number': season,
|
||||
'episodes': [
|
||||
{'watched_at': ?watchedAt, 'number': _episode},
|
||||
{'watched_at': ?watchedAt, 'number': number},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Build a `POST /sync/history/remove` body that removes this item from history.
|
||||
Map<String, dynamic> toHistoryRemoveBody() {
|
||||
if (isMovie) {
|
||||
return {
|
||||
Map<String, dynamic> toHistoryRemoveBody() => switch (this) {
|
||||
TraktScrobbleMovieRequest(:final ids) => {
|
||||
'movies': [
|
||||
{'ids': _movieIds!.toJson()},
|
||||
{'ids': ids.toJson()},
|
||||
],
|
||||
};
|
||||
}
|
||||
return {
|
||||
},
|
||||
TraktScrobbleEpisodeRequest(:final showIds, :final season, :final number) => {
|
||||
'shows': [
|
||||
{
|
||||
'ids': _showIds!.toJson(),
|
||||
'ids': showIds.toJson(),
|
||||
'seasons': [
|
||||
{
|
||||
'number': _season,
|
||||
'number': season,
|
||||
'episodes': [
|
||||
{'number': _episode},
|
||||
{'number': number},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'trakt_scrobble_request.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$TraktScrobbleRequest {
|
||||
|
||||
double? get progress;
|
||||
/// Create a copy of TraktScrobbleRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$TraktScrobbleRequestCopyWith<TraktScrobbleRequest> get copyWith => _$TraktScrobbleRequestCopyWithImpl<TraktScrobbleRequest>(this as TraktScrobbleRequest, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TraktScrobbleRequest&&(identical(other.progress, progress) || other.progress == progress));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,progress);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TraktScrobbleRequest(progress: $progress)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $TraktScrobbleRequestCopyWith<$Res> {
|
||||
factory $TraktScrobbleRequestCopyWith(TraktScrobbleRequest value, $Res Function(TraktScrobbleRequest) _then) = _$TraktScrobbleRequestCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
double? progress
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$TraktScrobbleRequestCopyWithImpl<$Res>
|
||||
implements $TraktScrobbleRequestCopyWith<$Res> {
|
||||
_$TraktScrobbleRequestCopyWithImpl(this._self, this._then);
|
||||
|
||||
final TraktScrobbleRequest _self;
|
||||
final $Res Function(TraktScrobbleRequest) _then;
|
||||
|
||||
/// Create a copy of TraktScrobbleRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? progress = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
progress: freezed == progress ? _self.progress : progress // ignore: cast_nullable_to_non_nullable
|
||||
as double?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [TraktScrobbleRequest].
|
||||
extension TraktScrobbleRequestPatterns on TraktScrobbleRequest {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( TraktScrobbleMovieRequest value)? movie,TResult Function( TraktScrobbleEpisodeRequest value)? episode,required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case TraktScrobbleMovieRequest() when movie != null:
|
||||
return movie(_that);case TraktScrobbleEpisodeRequest() when episode != null:
|
||||
return episode(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( TraktScrobbleMovieRequest value) movie,required TResult Function( TraktScrobbleEpisodeRequest value) episode,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case TraktScrobbleMovieRequest():
|
||||
return movie(_that);case TraktScrobbleEpisodeRequest():
|
||||
return episode(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( TraktScrobbleMovieRequest value)? movie,TResult? Function( TraktScrobbleEpisodeRequest value)? episode,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case TraktScrobbleMovieRequest() when movie != null:
|
||||
return movie(_that);case TraktScrobbleEpisodeRequest() when episode != null:
|
||||
return episode(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( TraktIds ids, double? progress)? movie,TResult Function( TraktIds showIds, int season, int number, double? progress)? episode,required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case TraktScrobbleMovieRequest() when movie != null:
|
||||
return movie(_that.ids,_that.progress);case TraktScrobbleEpisodeRequest() when episode != null:
|
||||
return episode(_that.showIds,_that.season,_that.number,_that.progress);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( TraktIds ids, double? progress) movie,required TResult Function( TraktIds showIds, int season, int number, double? progress) episode,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case TraktScrobbleMovieRequest():
|
||||
return movie(_that.ids,_that.progress);case TraktScrobbleEpisodeRequest():
|
||||
return episode(_that.showIds,_that.season,_that.number,_that.progress);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( TraktIds ids, double? progress)? movie,TResult? Function( TraktIds showIds, int season, int number, double? progress)? episode,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case TraktScrobbleMovieRequest() when movie != null:
|
||||
return movie(_that.ids,_that.progress);case TraktScrobbleEpisodeRequest() when episode != null:
|
||||
return episode(_that.showIds,_that.season,_that.number,_that.progress);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class TraktScrobbleMovieRequest extends TraktScrobbleRequest {
|
||||
const TraktScrobbleMovieRequest({required this.ids, this.progress}): super._();
|
||||
|
||||
|
||||
final TraktIds ids;
|
||||
@override final double? progress;
|
||||
|
||||
/// Create a copy of TraktScrobbleRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$TraktScrobbleMovieRequestCopyWith<TraktScrobbleMovieRequest> get copyWith => _$TraktScrobbleMovieRequestCopyWithImpl<TraktScrobbleMovieRequest>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TraktScrobbleMovieRequest&&(identical(other.ids, ids) || other.ids == ids)&&(identical(other.progress, progress) || other.progress == progress));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,ids,progress);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TraktScrobbleRequest.movie(ids: $ids, progress: $progress)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $TraktScrobbleMovieRequestCopyWith<$Res> implements $TraktScrobbleRequestCopyWith<$Res> {
|
||||
factory $TraktScrobbleMovieRequestCopyWith(TraktScrobbleMovieRequest value, $Res Function(TraktScrobbleMovieRequest) _then) = _$TraktScrobbleMovieRequestCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
TraktIds ids, double? progress
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$TraktScrobbleMovieRequestCopyWithImpl<$Res>
|
||||
implements $TraktScrobbleMovieRequestCopyWith<$Res> {
|
||||
_$TraktScrobbleMovieRequestCopyWithImpl(this._self, this._then);
|
||||
|
||||
final TraktScrobbleMovieRequest _self;
|
||||
final $Res Function(TraktScrobbleMovieRequest) _then;
|
||||
|
||||
/// Create a copy of TraktScrobbleRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? ids = null,Object? progress = freezed,}) {
|
||||
return _then(TraktScrobbleMovieRequest(
|
||||
ids: null == ids ? _self.ids : ids // ignore: cast_nullable_to_non_nullable
|
||||
as TraktIds,progress: freezed == progress ? _self.progress : progress // ignore: cast_nullable_to_non_nullable
|
||||
as double?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class TraktScrobbleEpisodeRequest extends TraktScrobbleRequest {
|
||||
const TraktScrobbleEpisodeRequest({required this.showIds, required this.season, required this.number, this.progress}): super._();
|
||||
|
||||
|
||||
final TraktIds showIds;
|
||||
final int season;
|
||||
final int number;
|
||||
@override final double? progress;
|
||||
|
||||
/// Create a copy of TraktScrobbleRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$TraktScrobbleEpisodeRequestCopyWith<TraktScrobbleEpisodeRequest> get copyWith => _$TraktScrobbleEpisodeRequestCopyWithImpl<TraktScrobbleEpisodeRequest>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TraktScrobbleEpisodeRequest&&(identical(other.showIds, showIds) || other.showIds == showIds)&&(identical(other.season, season) || other.season == season)&&(identical(other.number, number) || other.number == number)&&(identical(other.progress, progress) || other.progress == progress));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,showIds,season,number,progress);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'TraktScrobbleRequest.episode(showIds: $showIds, season: $season, number: $number, progress: $progress)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $TraktScrobbleEpisodeRequestCopyWith<$Res> implements $TraktScrobbleRequestCopyWith<$Res> {
|
||||
factory $TraktScrobbleEpisodeRequestCopyWith(TraktScrobbleEpisodeRequest value, $Res Function(TraktScrobbleEpisodeRequest) _then) = _$TraktScrobbleEpisodeRequestCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
TraktIds showIds, int season, int number, double? progress
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$TraktScrobbleEpisodeRequestCopyWithImpl<$Res>
|
||||
implements $TraktScrobbleEpisodeRequestCopyWith<$Res> {
|
||||
_$TraktScrobbleEpisodeRequestCopyWithImpl(this._self, this._then);
|
||||
|
||||
final TraktScrobbleEpisodeRequest _self;
|
||||
final $Res Function(TraktScrobbleEpisodeRequest) _then;
|
||||
|
||||
/// Create a copy of TraktScrobbleRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? showIds = null,Object? season = null,Object? number = null,Object? progress = freezed,}) {
|
||||
return _then(TraktScrobbleEpisodeRequest(
|
||||
showIds: null == showIds ? _self.showIds : showIds // ignore: cast_nullable_to_non_nullable
|
||||
as TraktIds,season: null == season ? _self.season : season // ignore: cast_nullable_to_non_nullable
|
||||
as int,number: null == number ? _self.number : number // ignore: cast_nullable_to_non_nullable
|
||||
as int,progress: freezed == progress ? _self.progress : progress // ignore: cast_nullable_to_non_nullable
|
||||
as double?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,4 +1,9 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'trakt_user.g.dart';
|
||||
|
||||
/// Minimal Trakt user info parsed from `GET /users/settings`.
|
||||
@JsonSerializable(createToJson: false)
|
||||
class TraktUser {
|
||||
final String username;
|
||||
final String? name;
|
||||
@@ -10,6 +15,6 @@ class TraktUser {
|
||||
if (user == null) {
|
||||
throw const FormatException('Trakt /users/settings response missing "user" field');
|
||||
}
|
||||
return TraktUser(username: user['username'] as String, name: user['name'] as String?);
|
||||
return _$TraktUserFromJson(user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'trakt_user.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
TraktUser _$TraktUserFromJson(Map<String, dynamic> json) => TraktUser(
|
||||
username: json['username'] as String,
|
||||
name: json['name'] as String?,
|
||||
);
|
||||
+66
-142
@@ -1,95 +1,77 @@
|
||||
class BufferRange {
|
||||
final Duration start;
|
||||
final Duration end;
|
||||
const BufferRange({required this.start, required this.end});
|
||||
// ignore_for_file: invalid_annotation_target
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'models.freezed.dart';
|
||||
|
||||
@freezed
|
||||
sealed class BufferRange with _$BufferRange {
|
||||
const factory BufferRange({required Duration start, required Duration end}) = _BufferRange;
|
||||
}
|
||||
|
||||
/// [cause] is an optional machine-readable tag (e.g. `server-http-500`),
|
||||
/// letting the UI branch without parsing [message].
|
||||
class PlayerError {
|
||||
@Freezed(toStringOverride: false)
|
||||
sealed class PlayerError with _$PlayerError {
|
||||
const PlayerError._();
|
||||
|
||||
const factory PlayerError(String message, {String? cause}) = _PlayerError;
|
||||
|
||||
/// Cause tag for a server-side HTTP 500 — shared-user bandwidth or
|
||||
/// transcoding limit rejection set by the server owner.
|
||||
static const String serverHttp500 = 'server-http-500';
|
||||
|
||||
final String message;
|
||||
final String? cause;
|
||||
const PlayerError(this.message, {this.cause});
|
||||
|
||||
@override
|
||||
String toString() => message;
|
||||
}
|
||||
|
||||
enum PlayerLogLevel { none, fatal, error, warn, info, verbose, debug, trace }
|
||||
|
||||
class AudioTrack {
|
||||
final String id;
|
||||
final String? title;
|
||||
final String? language;
|
||||
final String? codec;
|
||||
final int? channels;
|
||||
int? get channelsCount => channels;
|
||||
final int? sampleRate;
|
||||
final int? bitrate;
|
||||
final bool isDefault;
|
||||
final bool isForced;
|
||||
@freezed
|
||||
sealed class AudioTrack with _$AudioTrack {
|
||||
const AudioTrack._();
|
||||
|
||||
const AudioTrack({
|
||||
required this.id,
|
||||
this.title,
|
||||
this.language,
|
||||
this.codec,
|
||||
this.channels,
|
||||
this.sampleRate,
|
||||
this.bitrate,
|
||||
this.isDefault = false,
|
||||
this.isForced = false,
|
||||
});
|
||||
const factory AudioTrack({
|
||||
required String id,
|
||||
String? title,
|
||||
String? language,
|
||||
String? codec,
|
||||
int? channels,
|
||||
int? sampleRate,
|
||||
int? bitrate,
|
||||
@Default(false) bool isDefault,
|
||||
@Default(false) bool isForced,
|
||||
}) = _AudioTrack;
|
||||
|
||||
static const auto = AudioTrack(id: 'auto', title: 'Auto');
|
||||
|
||||
static const off = AudioTrack(id: 'no', title: 'Off');
|
||||
|
||||
int? get channelsCount => channels;
|
||||
|
||||
String get displayName {
|
||||
if (title != null && title!.isNotEmpty) return title!;
|
||||
if (language != null && language!.isNotEmpty) return language!;
|
||||
return 'Track $id';
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'AudioTrack($id, $displayName)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) || other is AudioTrack && runtimeType == other.runtimeType && id == other.id;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
|
||||
class SubtitleTrack {
|
||||
final String id;
|
||||
final String? title;
|
||||
final String? language;
|
||||
final String? codec;
|
||||
final bool isDefault;
|
||||
final bool isForced;
|
||||
final bool isExternal;
|
||||
final String? uri;
|
||||
@freezed
|
||||
sealed class SubtitleTrack with _$SubtitleTrack {
|
||||
const SubtitleTrack._();
|
||||
|
||||
const SubtitleTrack({
|
||||
required this.id,
|
||||
this.title,
|
||||
this.language,
|
||||
this.codec,
|
||||
this.isDefault = false,
|
||||
this.isForced = false,
|
||||
this.isExternal = false,
|
||||
this.uri,
|
||||
});
|
||||
const factory SubtitleTrack({
|
||||
required String id,
|
||||
String? title,
|
||||
String? language,
|
||||
String? codec,
|
||||
@Default(false) bool isDefault,
|
||||
@Default(false) bool isForced,
|
||||
@Default(false) bool isExternal,
|
||||
String? uri,
|
||||
}) = _SubtitleTrack;
|
||||
|
||||
factory SubtitleTrack.uri(String uri, {String? title, String? language}) {
|
||||
return SubtitleTrack(id: 'external:$uri', title: title, language: language, isExternal: true, uri: uri);
|
||||
}
|
||||
factory SubtitleTrack.uri(String uri, {String? title, String? language}) =>
|
||||
SubtitleTrack(id: 'external:$uri', title: title, language: language, isExternal: true, uri: uri);
|
||||
|
||||
static const auto = SubtitleTrack(id: 'auto', title: 'Auto');
|
||||
|
||||
@@ -101,103 +83,45 @@ class SubtitleTrack {
|
||||
if (isExternal) return 'External';
|
||||
return 'Track $id';
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'SubtitleTrack($id, $displayName)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) || other is SubtitleTrack && runtimeType == other.runtimeType && id == other.id;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
|
||||
class Tracks {
|
||||
final List<AudioTrack> audio;
|
||||
final List<SubtitleTrack> subtitle;
|
||||
@Freezed(toStringOverride: false)
|
||||
sealed class Tracks with _$Tracks {
|
||||
const Tracks._();
|
||||
|
||||
const Tracks({this.audio = const [], this.subtitle = const []});
|
||||
|
||||
Tracks copyWith({List<AudioTrack>? audio, List<SubtitleTrack>? subtitle}) {
|
||||
return Tracks(audio: audio ?? this.audio, subtitle: subtitle ?? this.subtitle);
|
||||
}
|
||||
const factory Tracks({
|
||||
@Default(<AudioTrack>[]) List<AudioTrack> audio,
|
||||
@Default(<SubtitleTrack>[]) List<SubtitleTrack> subtitle,
|
||||
}) = _Tracks;
|
||||
|
||||
@override
|
||||
String toString() => 'Tracks(audio: ${audio.length}, subtitle: ${subtitle.length})';
|
||||
}
|
||||
|
||||
/// Sentinel value used to distinguish "not provided" from "explicitly set to null" in copyWith.
|
||||
const _sentinel = Object();
|
||||
|
||||
class TrackSelection {
|
||||
final AudioTrack? audio;
|
||||
final SubtitleTrack? subtitle;
|
||||
final SubtitleTrack? secondarySubtitle;
|
||||
|
||||
const TrackSelection({this.audio, this.subtitle, this.secondarySubtitle});
|
||||
|
||||
/// Creates a copy with the given fields replaced.
|
||||
/// Use [secondarySubtitle] with explicit null to clear the secondary subtitle.
|
||||
TrackSelection copyWith({AudioTrack? audio, SubtitleTrack? subtitle, Object? secondarySubtitle = _sentinel}) {
|
||||
return TrackSelection(
|
||||
audio: audio ?? this.audio,
|
||||
subtitle: subtitle ?? this.subtitle,
|
||||
secondarySubtitle: identical(secondarySubtitle, _sentinel)
|
||||
? this.secondarySubtitle
|
||||
: secondarySubtitle as SubtitleTrack?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'TrackSelection(audio: $audio, subtitle: $subtitle, secondarySubtitle: $secondarySubtitle)';
|
||||
@freezed
|
||||
sealed class TrackSelection with _$TrackSelection {
|
||||
const factory TrackSelection({AudioTrack? audio, SubtitleTrack? subtitle, SubtitleTrack? secondarySubtitle}) =
|
||||
_TrackSelection;
|
||||
}
|
||||
|
||||
class AudioDevice {
|
||||
final String name;
|
||||
final String description;
|
||||
|
||||
const AudioDevice({required this.name, this.description = ''});
|
||||
@freezed
|
||||
sealed class AudioDevice with _$AudioDevice {
|
||||
const factory AudioDevice({required String name, @Default('') String description}) = _AudioDevice;
|
||||
|
||||
static const auto = AudioDevice(name: 'auto', description: 'Auto');
|
||||
|
||||
@override
|
||||
String toString() => 'AudioDevice($name, $description)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) || other is AudioDevice && runtimeType == other.runtimeType && name == other.name;
|
||||
|
||||
@override
|
||||
int get hashCode => name.hashCode;
|
||||
}
|
||||
|
||||
class PlayerLog {
|
||||
final PlayerLogLevel level;
|
||||
final String prefix;
|
||||
final String text;
|
||||
@Freezed(toStringOverride: false)
|
||||
sealed class PlayerLog with _$PlayerLog {
|
||||
const PlayerLog._();
|
||||
|
||||
const PlayerLog({required this.level, required this.prefix, required this.text});
|
||||
const factory PlayerLog({required PlayerLogLevel level, required String prefix, required String text}) = _PlayerLog;
|
||||
|
||||
@override
|
||||
String toString() => '[$prefix] ${level.name}: $text';
|
||||
}
|
||||
|
||||
class Media {
|
||||
final String uri;
|
||||
final Map<String, String>? headers;
|
||||
final Duration? start;
|
||||
|
||||
const Media(this.uri, {this.headers, this.start});
|
||||
|
||||
@override
|
||||
String toString() => 'Media($uri)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is Media && runtimeType == other.runtimeType && uri == other.uri && start == other.start;
|
||||
|
||||
@override
|
||||
int get hashCode => uri.hashCode ^ start.hashCode;
|
||||
@freezed
|
||||
sealed class Media with _$Media {
|
||||
const factory Media(String uri, {Map<String, String>? headers, Duration? start}) = _Media;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -438,18 +438,18 @@ abstract class PlayerBase with PlayerStreamControllersMixin implements Player {
|
||||
selectedTrack = _state.tracks.audio.firstWhereOrNull((t) => t.id == id);
|
||||
}
|
||||
|
||||
if (selectedTrack == null) return;
|
||||
_state = _state.copyWith(track: _state.track.copyWith(audio: selectedTrack));
|
||||
trackController.add(_state.track);
|
||||
}
|
||||
|
||||
void updateSelectedSubtitleTrack(dynamic trackId) {
|
||||
final id = trackId?.toString();
|
||||
SubtitleTrack? selectedTrack;
|
||||
|
||||
selectedTrack = (id == null || id == 'no')
|
||||
final selectedTrack = (id == null || id == 'no')
|
||||
? SubtitleTrack.off
|
||||
: _state.tracks.subtitle.firstWhereOrNull((t) => t.id == id);
|
||||
|
||||
if (selectedTrack == null) return;
|
||||
_state = _state.copyWith(track: _state.track.copyWith(subtitle: selectedTrack));
|
||||
trackController.add(_state.track);
|
||||
}
|
||||
|
||||
+99
-106
@@ -1,80 +1,72 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import '../models/plex/plex_home_user.dart';
|
||||
|
||||
part 'profile.freezed.dart';
|
||||
|
||||
/// Top-level profile — the user-facing identity in the app.
|
||||
///
|
||||
/// Two kinds:
|
||||
/// - [ProfileKind.local]: a Plezy-only profile created by the user. May have
|
||||
/// - [LocalProfile]: a Plezy-only profile created by the user. May have
|
||||
/// an optional 4-digit PIN.
|
||||
/// - [ProfileKind.plexHome]: auto-surfaced from a connected Plex account's
|
||||
/// - [PlexHomeProfile]: auto-surfaced from a connected Plex account's
|
||||
/// Home users. PIN protection is handled server-side by Plex via the
|
||||
/// `/home/users/{uuid}/switch` flow — `pinHash` is unused.
|
||||
///
|
||||
/// A profile owns 1+ connections via the `profile_connections` join table.
|
||||
/// The join row carries the per-profile user-level token used to talk to
|
||||
/// each connection.
|
||||
class Profile {
|
||||
final String id;
|
||||
final ProfileKind kind;
|
||||
final String displayName;
|
||||
final String? avatarThumbUrl;
|
||||
@freezed
|
||||
sealed class Profile with _$Profile {
|
||||
const Profile._();
|
||||
|
||||
/// Hashed PIN if set — only meaningful for [ProfileKind.local]. The raw
|
||||
/// PIN is never persisted; see [computePinHash].
|
||||
final String? pinHash;
|
||||
const factory Profile.local({
|
||||
required String id,
|
||||
required String displayName,
|
||||
String? avatarThumbUrl,
|
||||
|
||||
/// For [ProfileKind.plexHome]: the parent Plex account's connection id.
|
||||
/// `null` for local profiles.
|
||||
final String? parentConnectionId;
|
||||
/// Hashed PIN if set. The raw PIN is never persisted; see [computePinHash].
|
||||
String? pinHash,
|
||||
@Default(0) int sortOrder,
|
||||
required DateTime createdAt,
|
||||
DateTime? lastUsedAt,
|
||||
}) = LocalProfile;
|
||||
|
||||
/// For [ProfileKind.plexHome]: the Plex Home user UUID. Used by the
|
||||
/// active-profile binder to call `/home/users/{uuid}/switch`. `null` for
|
||||
/// local profiles.
|
||||
final String? plexHomeUserUuid;
|
||||
const factory Profile.plexHome({
|
||||
required String id,
|
||||
required String displayName,
|
||||
String? avatarThumbUrl,
|
||||
|
||||
/// Plex Home flags — only meaningful for [ProfileKind.plexHome].
|
||||
final bool plexRestricted;
|
||||
final bool plexAdmin;
|
||||
/// The parent Plex account's connection id.
|
||||
String? parentConnectionId,
|
||||
|
||||
/// The Plex Home user UUID. Used by the active-profile binder to call
|
||||
/// `/home/users/{uuid}/switch`.
|
||||
String? plexHomeUserUuid,
|
||||
@Default(false) bool plexRestricted,
|
||||
@Default(false) bool plexAdmin,
|
||||
|
||||
/// Plex's `protected` flag — true when the home user has a PIN that must
|
||||
/// be entered before `/home/users/{uuid}/switch` will succeed.
|
||||
final bool plexProtected;
|
||||
|
||||
final int sortOrder;
|
||||
final DateTime createdAt;
|
||||
final DateTime? lastUsedAt;
|
||||
|
||||
Profile({
|
||||
required this.id,
|
||||
required this.kind,
|
||||
required this.displayName,
|
||||
this.avatarThumbUrl,
|
||||
this.pinHash,
|
||||
this.parentConnectionId,
|
||||
this.plexHomeUserUuid,
|
||||
this.plexRestricted = false,
|
||||
this.plexAdmin = false,
|
||||
this.plexProtected = false,
|
||||
this.sortOrder = 0,
|
||||
required this.createdAt,
|
||||
this.lastUsedAt,
|
||||
});
|
||||
@Default(false) bool plexProtected,
|
||||
@Default(0) int sortOrder,
|
||||
required DateTime createdAt,
|
||||
DateTime? lastUsedAt,
|
||||
}) = PlexHomeProfile;
|
||||
|
||||
/// Construct an in-memory virtual `Profile` for a Plex Home user. These
|
||||
/// are never persisted — Plex owns the Home user list, so the picker
|
||||
/// reads them live from [PlexHomeService] and merges them with the local
|
||||
/// rows from [ProfileRegistry].
|
||||
/// rows from `ProfileRegistry`.
|
||||
factory Profile.virtualPlexHome({
|
||||
required String connectionId,
|
||||
required PlexHomeUser homeUser,
|
||||
DateTime? lastUsedAt,
|
||||
}) {
|
||||
return Profile(
|
||||
}) => Profile.plexHome(
|
||||
id: plexHomeProfileId(accountConnectionId: connectionId, homeUserUuid: homeUser.uuid),
|
||||
kind: ProfileKind.plexHome,
|
||||
displayName: homeUser.displayName,
|
||||
avatarThumbUrl: homeUser.thumb.isNotEmpty ? homeUser.thumb : null,
|
||||
parentConnectionId: connectionId,
|
||||
@@ -86,63 +78,6 @@ class Profile {
|
||||
createdAt: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
lastUsedAt: lastUsedAt,
|
||||
);
|
||||
}
|
||||
|
||||
bool get isLocal => kind == ProfileKind.local;
|
||||
bool get isPlexHome => kind == ProfileKind.plexHome;
|
||||
|
||||
/// True when entering this profile requires user-supplied PIN.
|
||||
///
|
||||
/// Locals: gated by their own [pinHash].
|
||||
/// Plex Home: gated by Plex's own protected flag (`plexProtected`).
|
||||
bool get isPinProtected => isLocal ? (pinHash != null && pinHash!.isNotEmpty) : plexProtected;
|
||||
|
||||
Profile copyWith({
|
||||
String? id,
|
||||
ProfileKind? kind,
|
||||
String? displayName,
|
||||
String? avatarThumbUrl,
|
||||
bool clearAvatar = false,
|
||||
String? pinHash,
|
||||
bool clearPin = false,
|
||||
String? parentConnectionId,
|
||||
String? plexHomeUserUuid,
|
||||
bool? plexRestricted,
|
||||
bool? plexAdmin,
|
||||
bool? plexProtected,
|
||||
int? sortOrder,
|
||||
DateTime? createdAt,
|
||||
DateTime? lastUsedAt,
|
||||
bool clearLastUsedAt = false,
|
||||
}) {
|
||||
return Profile(
|
||||
id: id ?? this.id,
|
||||
kind: kind ?? this.kind,
|
||||
displayName: displayName ?? this.displayName,
|
||||
avatarThumbUrl: clearAvatar ? null : (avatarThumbUrl ?? this.avatarThumbUrl),
|
||||
pinHash: clearPin ? null : (pinHash ?? this.pinHash),
|
||||
parentConnectionId: parentConnectionId ?? this.parentConnectionId,
|
||||
plexHomeUserUuid: plexHomeUserUuid ?? this.plexHomeUserUuid,
|
||||
plexRestricted: plexRestricted ?? this.plexRestricted,
|
||||
plexAdmin: plexAdmin ?? this.plexAdmin,
|
||||
plexProtected: plexProtected ?? this.plexProtected,
|
||||
sortOrder: sortOrder ?? this.sortOrder,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
lastUsedAt: clearLastUsedAt ? null : (lastUsedAt ?? this.lastUsedAt),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, Object?> toConfigJson() {
|
||||
return switch (kind) {
|
||||
ProfileKind.local => {'pinHash': pinHash},
|
||||
ProfileKind.plexHome => {
|
||||
'parentConnectionId': parentConnectionId,
|
||||
'restricted': plexRestricted,
|
||||
'admin': plexAdmin,
|
||||
'protected': plexProtected,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
factory Profile.fromRow({
|
||||
required String id,
|
||||
@@ -156,9 +91,8 @@ class Profile {
|
||||
}) {
|
||||
final parsedKind = ProfileKind.fromId(kind);
|
||||
return switch (parsedKind) {
|
||||
ProfileKind.local => Profile(
|
||||
ProfileKind.local => Profile.local(
|
||||
id: id,
|
||||
kind: parsedKind,
|
||||
displayName: displayName,
|
||||
avatarThumbUrl: avatarThumbUrl,
|
||||
pinHash: json['pinHash'] as String?,
|
||||
@@ -166,9 +100,8 @@ class Profile {
|
||||
createdAt: createdAt,
|
||||
lastUsedAt: lastUsedAt,
|
||||
),
|
||||
ProfileKind.plexHome => Profile(
|
||||
ProfileKind.plexHome => Profile.plexHome(
|
||||
id: id,
|
||||
kind: parsedKind,
|
||||
displayName: displayName,
|
||||
avatarThumbUrl: avatarThumbUrl,
|
||||
parentConnectionId: json['parentConnectionId'] as String?,
|
||||
@@ -181,6 +114,66 @@ class Profile {
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
bool get isLocal => this is LocalProfile;
|
||||
bool get isPlexHome => this is PlexHomeProfile;
|
||||
|
||||
ProfileKind get kind => switch (this) {
|
||||
LocalProfile() => ProfileKind.local,
|
||||
PlexHomeProfile() => ProfileKind.plexHome,
|
||||
};
|
||||
|
||||
/// True when entering this profile requires user-supplied PIN.
|
||||
///
|
||||
/// Locals: gated by their own [pinHash].
|
||||
/// Plex Home: gated by Plex's own protected flag (`plexProtected`).
|
||||
bool get isPinProtected => switch (this) {
|
||||
LocalProfile(:final pinHash) => pinHash != null && pinHash.isNotEmpty,
|
||||
PlexHomeProfile(:final plexProtected) => plexProtected,
|
||||
};
|
||||
|
||||
/// Hashed PIN, only set for [LocalProfile]. Returns null for plexHome.
|
||||
String? get pinHash => switch (this) {
|
||||
LocalProfile(:final pinHash) => pinHash,
|
||||
PlexHomeProfile() => null,
|
||||
};
|
||||
|
||||
/// Parent Plex account connection id, only set for [PlexHomeProfile].
|
||||
String? get parentConnectionId => switch (this) {
|
||||
LocalProfile() => null,
|
||||
PlexHomeProfile(:final parentConnectionId) => parentConnectionId,
|
||||
};
|
||||
|
||||
/// Plex Home user UUID, only set for [PlexHomeProfile].
|
||||
String? get plexHomeUserUuid => switch (this) {
|
||||
LocalProfile() => null,
|
||||
PlexHomeProfile(:final plexHomeUserUuid) => plexHomeUserUuid,
|
||||
};
|
||||
|
||||
bool get plexRestricted => switch (this) {
|
||||
LocalProfile() => false,
|
||||
PlexHomeProfile(:final plexRestricted) => plexRestricted,
|
||||
};
|
||||
|
||||
bool get plexAdmin => switch (this) {
|
||||
LocalProfile() => false,
|
||||
PlexHomeProfile(:final plexAdmin) => plexAdmin,
|
||||
};
|
||||
|
||||
bool get plexProtected => switch (this) {
|
||||
LocalProfile() => false,
|
||||
PlexHomeProfile(:final plexProtected) => plexProtected,
|
||||
};
|
||||
|
||||
Map<String, Object?> toConfigJson() => switch (this) {
|
||||
LocalProfile(:final pinHash) => {'pinHash': pinHash},
|
||||
PlexHomeProfile(:final parentConnectionId, :final plexRestricted, :final plexAdmin, :final plexProtected) => {
|
||||
'parentConnectionId': parentConnectionId,
|
||||
'restricted': plexRestricted,
|
||||
'admin': plexAdmin,
|
||||
'protected': plexProtected,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
enum ProfileKind {
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'profile.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$Profile {
|
||||
|
||||
String get id; String get displayName; String? get avatarThumbUrl; int get sortOrder; DateTime get createdAt; DateTime? get lastUsedAt;
|
||||
/// Create a copy of Profile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ProfileCopyWith<Profile> get copyWith => _$ProfileCopyWithImpl<Profile>(this as Profile, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is Profile&&(identical(other.id, id) || other.id == id)&&(identical(other.displayName, displayName) || other.displayName == displayName)&&(identical(other.avatarThumbUrl, avatarThumbUrl) || other.avatarThumbUrl == avatarThumbUrl)&&(identical(other.sortOrder, sortOrder) || other.sortOrder == sortOrder)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.lastUsedAt, lastUsedAt) || other.lastUsedAt == lastUsedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,displayName,avatarThumbUrl,sortOrder,createdAt,lastUsedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Profile(id: $id, displayName: $displayName, avatarThumbUrl: $avatarThumbUrl, sortOrder: $sortOrder, createdAt: $createdAt, lastUsedAt: $lastUsedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ProfileCopyWith<$Res> {
|
||||
factory $ProfileCopyWith(Profile value, $Res Function(Profile) _then) = _$ProfileCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String displayName, String? avatarThumbUrl, int sortOrder, DateTime createdAt, DateTime? lastUsedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ProfileCopyWithImpl<$Res>
|
||||
implements $ProfileCopyWith<$Res> {
|
||||
_$ProfileCopyWithImpl(this._self, this._then);
|
||||
|
||||
final Profile _self;
|
||||
final $Res Function(Profile) _then;
|
||||
|
||||
/// Create a copy of Profile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? displayName = null,Object? avatarThumbUrl = freezed,Object? sortOrder = null,Object? createdAt = null,Object? lastUsedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,displayName: null == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
|
||||
as String,avatarThumbUrl: freezed == avatarThumbUrl ? _self.avatarThumbUrl : avatarThumbUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,sortOrder: null == sortOrder ? _self.sortOrder : sortOrder // ignore: cast_nullable_to_non_nullable
|
||||
as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,lastUsedAt: freezed == lastUsedAt ? _self.lastUsedAt : lastUsedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [Profile].
|
||||
extension ProfilePatterns on Profile {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( LocalProfile value)? local,TResult Function( PlexHomeProfile value)? plexHome,required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case LocalProfile() when local != null:
|
||||
return local(_that);case PlexHomeProfile() when plexHome != null:
|
||||
return plexHome(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( LocalProfile value) local,required TResult Function( PlexHomeProfile value) plexHome,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case LocalProfile():
|
||||
return local(_that);case PlexHomeProfile():
|
||||
return plexHome(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( LocalProfile value)? local,TResult? Function( PlexHomeProfile value)? plexHome,}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case LocalProfile() when local != null:
|
||||
return local(_that);case PlexHomeProfile() when plexHome != null:
|
||||
return plexHome(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String id, String displayName, String? avatarThumbUrl, String? pinHash, int sortOrder, DateTime createdAt, DateTime? lastUsedAt)? local,TResult Function( String id, String displayName, String? avatarThumbUrl, String? parentConnectionId, String? plexHomeUserUuid, bool plexRestricted, bool plexAdmin, bool plexProtected, int sortOrder, DateTime createdAt, DateTime? lastUsedAt)? plexHome,required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case LocalProfile() when local != null:
|
||||
return local(_that.id,_that.displayName,_that.avatarThumbUrl,_that.pinHash,_that.sortOrder,_that.createdAt,_that.lastUsedAt);case PlexHomeProfile() when plexHome != null:
|
||||
return plexHome(_that.id,_that.displayName,_that.avatarThumbUrl,_that.parentConnectionId,_that.plexHomeUserUuid,_that.plexRestricted,_that.plexAdmin,_that.plexProtected,_that.sortOrder,_that.createdAt,_that.lastUsedAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String id, String displayName, String? avatarThumbUrl, String? pinHash, int sortOrder, DateTime createdAt, DateTime? lastUsedAt) local,required TResult Function( String id, String displayName, String? avatarThumbUrl, String? parentConnectionId, String? plexHomeUserUuid, bool plexRestricted, bool plexAdmin, bool plexProtected, int sortOrder, DateTime createdAt, DateTime? lastUsedAt) plexHome,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case LocalProfile():
|
||||
return local(_that.id,_that.displayName,_that.avatarThumbUrl,_that.pinHash,_that.sortOrder,_that.createdAt,_that.lastUsedAt);case PlexHomeProfile():
|
||||
return plexHome(_that.id,_that.displayName,_that.avatarThumbUrl,_that.parentConnectionId,_that.plexHomeUserUuid,_that.plexRestricted,_that.plexAdmin,_that.plexProtected,_that.sortOrder,_that.createdAt,_that.lastUsedAt);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String id, String displayName, String? avatarThumbUrl, String? pinHash, int sortOrder, DateTime createdAt, DateTime? lastUsedAt)? local,TResult? Function( String id, String displayName, String? avatarThumbUrl, String? parentConnectionId, String? plexHomeUserUuid, bool plexRestricted, bool plexAdmin, bool plexProtected, int sortOrder, DateTime createdAt, DateTime? lastUsedAt)? plexHome,}) {final _that = this;
|
||||
switch (_that) {
|
||||
case LocalProfile() when local != null:
|
||||
return local(_that.id,_that.displayName,_that.avatarThumbUrl,_that.pinHash,_that.sortOrder,_that.createdAt,_that.lastUsedAt);case PlexHomeProfile() when plexHome != null:
|
||||
return plexHome(_that.id,_that.displayName,_that.avatarThumbUrl,_that.parentConnectionId,_that.plexHomeUserUuid,_that.plexRestricted,_that.plexAdmin,_that.plexProtected,_that.sortOrder,_that.createdAt,_that.lastUsedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class LocalProfile extends Profile {
|
||||
const LocalProfile({required this.id, required this.displayName, this.avatarThumbUrl, this.pinHash, this.sortOrder = 0, required this.createdAt, this.lastUsedAt}): super._();
|
||||
|
||||
|
||||
@override final String id;
|
||||
@override final String displayName;
|
||||
@override final String? avatarThumbUrl;
|
||||
/// Hashed PIN if set. The raw PIN is never persisted; see [computePinHash].
|
||||
final String? pinHash;
|
||||
@override@JsonKey() final int sortOrder;
|
||||
@override final DateTime createdAt;
|
||||
@override final DateTime? lastUsedAt;
|
||||
|
||||
/// Create a copy of Profile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$LocalProfileCopyWith<LocalProfile> get copyWith => _$LocalProfileCopyWithImpl<LocalProfile>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is LocalProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.displayName, displayName) || other.displayName == displayName)&&(identical(other.avatarThumbUrl, avatarThumbUrl) || other.avatarThumbUrl == avatarThumbUrl)&&(identical(other.pinHash, pinHash) || other.pinHash == pinHash)&&(identical(other.sortOrder, sortOrder) || other.sortOrder == sortOrder)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.lastUsedAt, lastUsedAt) || other.lastUsedAt == lastUsedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,displayName,avatarThumbUrl,pinHash,sortOrder,createdAt,lastUsedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Profile.local(id: $id, displayName: $displayName, avatarThumbUrl: $avatarThumbUrl, pinHash: $pinHash, sortOrder: $sortOrder, createdAt: $createdAt, lastUsedAt: $lastUsedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $LocalProfileCopyWith<$Res> implements $ProfileCopyWith<$Res> {
|
||||
factory $LocalProfileCopyWith(LocalProfile value, $Res Function(LocalProfile) _then) = _$LocalProfileCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String displayName, String? avatarThumbUrl, String? pinHash, int sortOrder, DateTime createdAt, DateTime? lastUsedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$LocalProfileCopyWithImpl<$Res>
|
||||
implements $LocalProfileCopyWith<$Res> {
|
||||
_$LocalProfileCopyWithImpl(this._self, this._then);
|
||||
|
||||
final LocalProfile _self;
|
||||
final $Res Function(LocalProfile) _then;
|
||||
|
||||
/// Create a copy of Profile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? displayName = null,Object? avatarThumbUrl = freezed,Object? pinHash = freezed,Object? sortOrder = null,Object? createdAt = null,Object? lastUsedAt = freezed,}) {
|
||||
return _then(LocalProfile(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,displayName: null == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
|
||||
as String,avatarThumbUrl: freezed == avatarThumbUrl ? _self.avatarThumbUrl : avatarThumbUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,pinHash: freezed == pinHash ? _self.pinHash : pinHash // ignore: cast_nullable_to_non_nullable
|
||||
as String?,sortOrder: null == sortOrder ? _self.sortOrder : sortOrder // ignore: cast_nullable_to_non_nullable
|
||||
as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,lastUsedAt: freezed == lastUsedAt ? _self.lastUsedAt : lastUsedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class PlexHomeProfile extends Profile {
|
||||
const PlexHomeProfile({required this.id, required this.displayName, this.avatarThumbUrl, this.parentConnectionId, this.plexHomeUserUuid, this.plexRestricted = false, this.plexAdmin = false, this.plexProtected = false, this.sortOrder = 0, required this.createdAt, this.lastUsedAt}): super._();
|
||||
|
||||
|
||||
@override final String id;
|
||||
@override final String displayName;
|
||||
@override final String? avatarThumbUrl;
|
||||
/// The parent Plex account's connection id.
|
||||
final String? parentConnectionId;
|
||||
/// The Plex Home user UUID. Used by the active-profile binder to call
|
||||
/// `/home/users/{uuid}/switch`.
|
||||
final String? plexHomeUserUuid;
|
||||
@JsonKey() final bool plexRestricted;
|
||||
@JsonKey() final bool plexAdmin;
|
||||
/// Plex's `protected` flag — true when the home user has a PIN that must
|
||||
/// be entered before `/home/users/{uuid}/switch` will succeed.
|
||||
@JsonKey() final bool plexProtected;
|
||||
@override@JsonKey() final int sortOrder;
|
||||
@override final DateTime createdAt;
|
||||
@override final DateTime? lastUsedAt;
|
||||
|
||||
/// Create a copy of Profile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$PlexHomeProfileCopyWith<PlexHomeProfile> get copyWith => _$PlexHomeProfileCopyWithImpl<PlexHomeProfile>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PlexHomeProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.displayName, displayName) || other.displayName == displayName)&&(identical(other.avatarThumbUrl, avatarThumbUrl) || other.avatarThumbUrl == avatarThumbUrl)&&(identical(other.parentConnectionId, parentConnectionId) || other.parentConnectionId == parentConnectionId)&&(identical(other.plexHomeUserUuid, plexHomeUserUuid) || other.plexHomeUserUuid == plexHomeUserUuid)&&(identical(other.plexRestricted, plexRestricted) || other.plexRestricted == plexRestricted)&&(identical(other.plexAdmin, plexAdmin) || other.plexAdmin == plexAdmin)&&(identical(other.plexProtected, plexProtected) || other.plexProtected == plexProtected)&&(identical(other.sortOrder, sortOrder) || other.sortOrder == sortOrder)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.lastUsedAt, lastUsedAt) || other.lastUsedAt == lastUsedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,displayName,avatarThumbUrl,parentConnectionId,plexHomeUserUuid,plexRestricted,plexAdmin,plexProtected,sortOrder,createdAt,lastUsedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Profile.plexHome(id: $id, displayName: $displayName, avatarThumbUrl: $avatarThumbUrl, parentConnectionId: $parentConnectionId, plexHomeUserUuid: $plexHomeUserUuid, plexRestricted: $plexRestricted, plexAdmin: $plexAdmin, plexProtected: $plexProtected, sortOrder: $sortOrder, createdAt: $createdAt, lastUsedAt: $lastUsedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $PlexHomeProfileCopyWith<$Res> implements $ProfileCopyWith<$Res> {
|
||||
factory $PlexHomeProfileCopyWith(PlexHomeProfile value, $Res Function(PlexHomeProfile) _then) = _$PlexHomeProfileCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String displayName, String? avatarThumbUrl, String? parentConnectionId, String? plexHomeUserUuid, bool plexRestricted, bool plexAdmin, bool plexProtected, int sortOrder, DateTime createdAt, DateTime? lastUsedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$PlexHomeProfileCopyWithImpl<$Res>
|
||||
implements $PlexHomeProfileCopyWith<$Res> {
|
||||
_$PlexHomeProfileCopyWithImpl(this._self, this._then);
|
||||
|
||||
final PlexHomeProfile _self;
|
||||
final $Res Function(PlexHomeProfile) _then;
|
||||
|
||||
/// Create a copy of Profile
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? displayName = null,Object? avatarThumbUrl = freezed,Object? parentConnectionId = freezed,Object? plexHomeUserUuid = freezed,Object? plexRestricted = null,Object? plexAdmin = null,Object? plexProtected = null,Object? sortOrder = null,Object? createdAt = null,Object? lastUsedAt = freezed,}) {
|
||||
return _then(PlexHomeProfile(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,displayName: null == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
|
||||
as String,avatarThumbUrl: freezed == avatarThumbUrl ? _self.avatarThumbUrl : avatarThumbUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,parentConnectionId: freezed == parentConnectionId ? _self.parentConnectionId : parentConnectionId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,plexHomeUserUuid: freezed == plexHomeUserUuid ? _self.plexHomeUserUuid : plexHomeUserUuid // ignore: cast_nullable_to_non_nullable
|
||||
as String?,plexRestricted: null == plexRestricted ? _self.plexRestricted : plexRestricted // ignore: cast_nullable_to_non_nullable
|
||||
as bool,plexAdmin: null == plexAdmin ? _self.plexAdmin : plexAdmin // ignore: cast_nullable_to_non_nullable
|
||||
as bool,plexProtected: null == plexProtected ? _self.plexProtected : plexProtected // ignore: cast_nullable_to_non_nullable
|
||||
as bool,sortOrder: null == sortOrder ? _self.sortOrder : sortOrder // ignore: cast_nullable_to_non_nullable
|
||||
as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,lastUsedAt: freezed == lastUsedAt ? _self.lastUsedAt : lastUsedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -1,3 +1,7 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'profile_connection.freezed.dart';
|
||||
|
||||
/// A binding between a [Profile] and a [Connection], carrying the
|
||||
/// per-profile user-level token used when the profile is active.
|
||||
///
|
||||
@@ -9,47 +13,19 @@
|
||||
///
|
||||
/// For Jellyfin: [userToken] mirrors the Connection's accessToken (one
|
||||
/// user per connection); [userIdentifier] is the Jellyfin user id.
|
||||
class ProfileConnection {
|
||||
final String profileId;
|
||||
final String connectionId;
|
||||
final String? userToken;
|
||||
final String userIdentifier;
|
||||
final bool isDefault;
|
||||
final DateTime? tokenAcquiredAt;
|
||||
final DateTime? lastUsedAt;
|
||||
@freezed
|
||||
sealed class ProfileConnection with _$ProfileConnection {
|
||||
const ProfileConnection._();
|
||||
|
||||
const ProfileConnection({
|
||||
required this.profileId,
|
||||
required this.connectionId,
|
||||
this.userToken,
|
||||
required this.userIdentifier,
|
||||
this.isDefault = false,
|
||||
this.tokenAcquiredAt,
|
||||
this.lastUsedAt,
|
||||
});
|
||||
const factory ProfileConnection({
|
||||
required String profileId,
|
||||
required String connectionId,
|
||||
String? userToken,
|
||||
required String userIdentifier,
|
||||
@Default(false) bool isDefault,
|
||||
DateTime? tokenAcquiredAt,
|
||||
DateTime? lastUsedAt,
|
||||
}) = _ProfileConnection;
|
||||
|
||||
bool get hasToken => userToken != null && userToken!.isNotEmpty;
|
||||
|
||||
ProfileConnection copyWith({
|
||||
String? profileId,
|
||||
String? connectionId,
|
||||
String? userToken,
|
||||
bool clearUserToken = false,
|
||||
String? userIdentifier,
|
||||
bool? isDefault,
|
||||
DateTime? tokenAcquiredAt,
|
||||
bool clearTokenAcquiredAt = false,
|
||||
DateTime? lastUsedAt,
|
||||
bool clearLastUsedAt = false,
|
||||
}) {
|
||||
return ProfileConnection(
|
||||
profileId: profileId ?? this.profileId,
|
||||
connectionId: connectionId ?? this.connectionId,
|
||||
userToken: clearUserToken ? null : (userToken ?? this.userToken),
|
||||
userIdentifier: userIdentifier ?? this.userIdentifier,
|
||||
isDefault: isDefault ?? this.isDefault,
|
||||
tokenAcquiredAt: clearTokenAcquiredAt ? null : (tokenAcquiredAt ?? this.tokenAcquiredAt),
|
||||
lastUsedAt: clearLastUsedAt ? null : (lastUsedAt ?? this.lastUsedAt),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'profile_connection.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$ProfileConnection {
|
||||
|
||||
String get profileId; String get connectionId; String? get userToken; String get userIdentifier; bool get isDefault; DateTime? get tokenAcquiredAt; DateTime? get lastUsedAt;
|
||||
/// Create a copy of ProfileConnection
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ProfileConnectionCopyWith<ProfileConnection> get copyWith => _$ProfileConnectionCopyWithImpl<ProfileConnection>(this as ProfileConnection, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is ProfileConnection&&(identical(other.profileId, profileId) || other.profileId == profileId)&&(identical(other.connectionId, connectionId) || other.connectionId == connectionId)&&(identical(other.userToken, userToken) || other.userToken == userToken)&&(identical(other.userIdentifier, userIdentifier) || other.userIdentifier == userIdentifier)&&(identical(other.isDefault, isDefault) || other.isDefault == isDefault)&&(identical(other.tokenAcquiredAt, tokenAcquiredAt) || other.tokenAcquiredAt == tokenAcquiredAt)&&(identical(other.lastUsedAt, lastUsedAt) || other.lastUsedAt == lastUsedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,profileId,connectionId,userToken,userIdentifier,isDefault,tokenAcquiredAt,lastUsedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfileConnection(profileId: $profileId, connectionId: $connectionId, userToken: $userToken, userIdentifier: $userIdentifier, isDefault: $isDefault, tokenAcquiredAt: $tokenAcquiredAt, lastUsedAt: $lastUsedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ProfileConnectionCopyWith<$Res> {
|
||||
factory $ProfileConnectionCopyWith(ProfileConnection value, $Res Function(ProfileConnection) _then) = _$ProfileConnectionCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String profileId, String connectionId, String? userToken, String userIdentifier, bool isDefault, DateTime? tokenAcquiredAt, DateTime? lastUsedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ProfileConnectionCopyWithImpl<$Res>
|
||||
implements $ProfileConnectionCopyWith<$Res> {
|
||||
_$ProfileConnectionCopyWithImpl(this._self, this._then);
|
||||
|
||||
final ProfileConnection _self;
|
||||
final $Res Function(ProfileConnection) _then;
|
||||
|
||||
/// Create a copy of ProfileConnection
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? profileId = null,Object? connectionId = null,Object? userToken = freezed,Object? userIdentifier = null,Object? isDefault = null,Object? tokenAcquiredAt = freezed,Object? lastUsedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
profileId: null == profileId ? _self.profileId : profileId // ignore: cast_nullable_to_non_nullable
|
||||
as String,connectionId: null == connectionId ? _self.connectionId : connectionId // ignore: cast_nullable_to_non_nullable
|
||||
as String,userToken: freezed == userToken ? _self.userToken : userToken // ignore: cast_nullable_to_non_nullable
|
||||
as String?,userIdentifier: null == userIdentifier ? _self.userIdentifier : userIdentifier // ignore: cast_nullable_to_non_nullable
|
||||
as String,isDefault: null == isDefault ? _self.isDefault : isDefault // ignore: cast_nullable_to_non_nullable
|
||||
as bool,tokenAcquiredAt: freezed == tokenAcquiredAt ? _self.tokenAcquiredAt : tokenAcquiredAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,lastUsedAt: freezed == lastUsedAt ? _self.lastUsedAt : lastUsedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [ProfileConnection].
|
||||
extension ProfileConnectionPatterns on ProfileConnection {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ProfileConnection value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ProfileConnection() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ProfileConnection value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ProfileConnection():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ProfileConnection value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _ProfileConnection() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String profileId, String connectionId, String? userToken, String userIdentifier, bool isDefault, DateTime? tokenAcquiredAt, DateTime? lastUsedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ProfileConnection() when $default != null:
|
||||
return $default(_that.profileId,_that.connectionId,_that.userToken,_that.userIdentifier,_that.isDefault,_that.tokenAcquiredAt,_that.lastUsedAt);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String profileId, String connectionId, String? userToken, String userIdentifier, bool isDefault, DateTime? tokenAcquiredAt, DateTime? lastUsedAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ProfileConnection():
|
||||
return $default(_that.profileId,_that.connectionId,_that.userToken,_that.userIdentifier,_that.isDefault,_that.tokenAcquiredAt,_that.lastUsedAt);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String profileId, String connectionId, String? userToken, String userIdentifier, bool isDefault, DateTime? tokenAcquiredAt, DateTime? lastUsedAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _ProfileConnection() when $default != null:
|
||||
return $default(_that.profileId,_that.connectionId,_that.userToken,_that.userIdentifier,_that.isDefault,_that.tokenAcquiredAt,_that.lastUsedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _ProfileConnection extends ProfileConnection {
|
||||
const _ProfileConnection({required this.profileId, required this.connectionId, this.userToken, required this.userIdentifier, this.isDefault = false, this.tokenAcquiredAt, this.lastUsedAt}): super._();
|
||||
|
||||
|
||||
@override final String profileId;
|
||||
@override final String connectionId;
|
||||
@override final String? userToken;
|
||||
@override final String userIdentifier;
|
||||
@override@JsonKey() final bool isDefault;
|
||||
@override final DateTime? tokenAcquiredAt;
|
||||
@override final DateTime? lastUsedAt;
|
||||
|
||||
/// Create a copy of ProfileConnection
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ProfileConnectionCopyWith<_ProfileConnection> get copyWith => __$ProfileConnectionCopyWithImpl<_ProfileConnection>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProfileConnection&&(identical(other.profileId, profileId) || other.profileId == profileId)&&(identical(other.connectionId, connectionId) || other.connectionId == connectionId)&&(identical(other.userToken, userToken) || other.userToken == userToken)&&(identical(other.userIdentifier, userIdentifier) || other.userIdentifier == userIdentifier)&&(identical(other.isDefault, isDefault) || other.isDefault == isDefault)&&(identical(other.tokenAcquiredAt, tokenAcquiredAt) || other.tokenAcquiredAt == tokenAcquiredAt)&&(identical(other.lastUsedAt, lastUsedAt) || other.lastUsedAt == lastUsedAt));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,profileId,connectionId,userToken,userIdentifier,isDefault,tokenAcquiredAt,lastUsedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfileConnection(profileId: $profileId, connectionId: $connectionId, userToken: $userToken, userIdentifier: $userIdentifier, isDefault: $isDefault, tokenAcquiredAt: $tokenAcquiredAt, lastUsedAt: $lastUsedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ProfileConnectionCopyWith<$Res> implements $ProfileConnectionCopyWith<$Res> {
|
||||
factory _$ProfileConnectionCopyWith(_ProfileConnection value, $Res Function(_ProfileConnection) _then) = __$ProfileConnectionCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String profileId, String connectionId, String? userToken, String userIdentifier, bool isDefault, DateTime? tokenAcquiredAt, DateTime? lastUsedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ProfileConnectionCopyWithImpl<$Res>
|
||||
implements _$ProfileConnectionCopyWith<$Res> {
|
||||
__$ProfileConnectionCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _ProfileConnection _self;
|
||||
final $Res Function(_ProfileConnection) _then;
|
||||
|
||||
/// Create a copy of ProfileConnection
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? profileId = null,Object? connectionId = null,Object? userToken = freezed,Object? userIdentifier = null,Object? isDefault = null,Object? tokenAcquiredAt = freezed,Object? lastUsedAt = freezed,}) {
|
||||
return _then(_ProfileConnection(
|
||||
profileId: null == profileId ? _self.profileId : profileId // ignore: cast_nullable_to_non_nullable
|
||||
as String,connectionId: null == connectionId ? _self.connectionId : connectionId // ignore: cast_nullable_to_non_nullable
|
||||
as String,userToken: freezed == userToken ? _self.userToken : userToken // ignore: cast_nullable_to_non_nullable
|
||||
as String?,userIdentifier: null == userIdentifier ? _self.userIdentifier : userIdentifier // ignore: cast_nullable_to_non_nullable
|
||||
as String,isDefault: null == isDefault ? _self.isDefault : isDefault // ignore: cast_nullable_to_non_nullable
|
||||
as bool,tokenAcquiredAt: freezed == tokenAcquiredAt ? _self.tokenAcquiredAt : tokenAcquiredAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,lastUsedAt: freezed == lastUsedAt ? _self.lastUsedAt : lastUsedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -459,7 +459,11 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
final contexts = List<RemoteAuthContext>.unmodifiable(_authContexts);
|
||||
final result = await _peerService!.createSessionForContexts(_deviceName, _platform, contexts);
|
||||
|
||||
_session = RemoteSession(role: RemoteSessionRole.host, status: RemoteSessionStatus.connected);
|
||||
_session = RemoteSession(
|
||||
role: RemoteSessionRole.host,
|
||||
status: RemoteSessionStatus.connected,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
safeNotifyListeners();
|
||||
|
||||
// Start LAN discovery broadcasting
|
||||
@@ -480,6 +484,7 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
role: RemoteSessionRole.host,
|
||||
status: RemoteSessionStatus.error,
|
||||
errorMessage: e.toString(),
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
safeNotifyListeners();
|
||||
}
|
||||
@@ -538,7 +543,11 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
_peerService = CompanionRemotePeerService();
|
||||
_setupPeerServiceListeners();
|
||||
|
||||
_session = RemoteSession(role: RemoteSessionRole.remote, status: RemoteSessionStatus.connecting);
|
||||
_session = RemoteSession(
|
||||
role: RemoteSessionRole.remote,
|
||||
status: RemoteSessionStatus.connecting,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
safeNotifyListeners();
|
||||
|
||||
try {
|
||||
@@ -582,7 +591,11 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
_peerService = CompanionRemotePeerService();
|
||||
_setupPeerServiceListeners();
|
||||
|
||||
_session = RemoteSession(role: RemoteSessionRole.remote, status: RemoteSessionStatus.connecting);
|
||||
_session = RemoteSession(
|
||||
role: RemoteSessionRole.remote,
|
||||
status: RemoteSessionStatus.connecting,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
safeNotifyListeners();
|
||||
|
||||
try {
|
||||
@@ -629,13 +642,13 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
_deviceDisconnectedSubscription = _peerService!.onDeviceDisconnected.listen((_) {
|
||||
appLogger.d('CompanionRemote: Device disconnected (intentional: $_intentionalDisconnect)');
|
||||
if (_intentionalDisconnect) {
|
||||
_session = _session?.copyWith(status: RemoteSessionStatus.disconnected, clearConnectedDevice: true);
|
||||
_session = _session?.copyWith(status: RemoteSessionStatus.disconnected, connectedDevice: null);
|
||||
safeNotifyListeners();
|
||||
} else if (isHost) {
|
||||
_session = _session?.copyWith(
|
||||
status: RemoteSessionStatus.reconnecting,
|
||||
clearConnectedDevice: true,
|
||||
clearErrorMessage: true,
|
||||
connectedDevice: null,
|
||||
errorMessage: null,
|
||||
);
|
||||
safeNotifyListeners();
|
||||
appLogger.d('CompanionRemote: Host waiting for client to reconnect');
|
||||
@@ -668,7 +681,7 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
|
||||
appLogger.d('CompanionRemote: Device info - name: $name, platform: $platform, role: $role');
|
||||
|
||||
final device = RemoteDevice(id: id, name: name, platform: platform);
|
||||
final device = RemoteDevice(id: id, name: name, platform: platform, connectedAt: DateTime.now());
|
||||
|
||||
_session = _session?.copyWith(connectedDevice: device);
|
||||
safeNotifyListeners();
|
||||
@@ -756,7 +769,7 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
_lastAuthContextId = _peerService!.selectedAuthContextId ?? authContextId;
|
||||
_lastHostClientId = _peerService!.selectedHostClientId ?? _lastHostClientId;
|
||||
|
||||
_session = _session?.copyWith(status: RemoteSessionStatus.connected, clearErrorMessage: true);
|
||||
_session = _session?.copyWith(status: RemoteSessionStatus.connected, errorMessage: null);
|
||||
_reconnectAttempts = 0;
|
||||
safeNotifyListeners();
|
||||
appLogger.d('CompanionRemote: Reconnected successfully');
|
||||
@@ -777,7 +790,7 @@ class CompanionRemoteProvider with ChangeNotifier, DisposableChangeNotifierMixin
|
||||
void cancelReconnect() {
|
||||
_reconnectTimer?.cancel();
|
||||
_reconnectAttempts = 0;
|
||||
_session = _session?.copyWith(status: RemoteSessionStatus.disconnected, clearConnectedDevice: true);
|
||||
_session = _session?.copyWith(status: RemoteSessionStatus.disconnected, connectedDevice: null);
|
||||
safeNotifyListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,9 +64,8 @@ class _AddLocalProfileScreenState extends State<AddLocalProfileScreen> with Cont
|
||||
setState(() => _saving = true);
|
||||
|
||||
final registry = context.read<ProfileRegistry>();
|
||||
final profile = Profile(
|
||||
final profile = Profile.local(
|
||||
id: 'local-${const Uuid().v4()}',
|
||||
kind: ProfileKind.local,
|
||||
displayName: name,
|
||||
pinHash: _pinHash,
|
||||
sortOrder: DateTime.now().millisecondsSinceEpoch,
|
||||
|
||||
@@ -87,14 +87,18 @@ class _ProfileDetailScreenState extends State<ProfileDetailScreen> with Controll
|
||||
onMismatch: (ctx) => showErrorSnackBar(ctx, t.profiles.pinsDontMatch),
|
||||
);
|
||||
if (pin == null || !mounted) return;
|
||||
final updated = _profile.copyWith(pinHash: computePinHash(pin));
|
||||
final profile = _profile;
|
||||
if (profile is! LocalProfile) return;
|
||||
final updated = profile.copyWith(pinHash: computePinHash(pin));
|
||||
await context.read<ProfileRegistry>().upsert(updated);
|
||||
if (!mounted) return;
|
||||
setState(() => _profile = updated);
|
||||
}
|
||||
|
||||
Future<void> _clearPin() async {
|
||||
final updated = _profile.copyWith(clearPin: true);
|
||||
final profile = _profile;
|
||||
if (profile is! LocalProfile) return;
|
||||
final updated = profile.copyWith(pinHash: null);
|
||||
await context.read<ProfileRegistry>().upsert(updated);
|
||||
if (!mounted) return;
|
||||
setState(() => _profile = updated);
|
||||
|
||||
@@ -264,9 +264,8 @@ class _AddJellyfinScreenState extends State<AddJellyfinScreen> with AsyncFormSta
|
||||
hasProfiles: activeProvider.profiles.isNotEmpty,
|
||||
)) {
|
||||
final now = DateTime.now();
|
||||
final profile = Profile(
|
||||
final profile = Profile.local(
|
||||
id: 'local-${const Uuid().v4()}',
|
||||
kind: ProfileKind.local,
|
||||
displayName: connection.userName.isNotEmpty ? connection.userName : connection.serverName,
|
||||
sortOrder: now.millisecondsSinceEpoch,
|
||||
createdAt: now,
|
||||
|
||||
@@ -343,7 +343,12 @@ class CompanionRemotePeerService with KeepaliveMixin {
|
||||
await _sendEncryptedToSocket(socket, jsonEncode({'type': 'authSuccess'}));
|
||||
|
||||
// Notify connection
|
||||
final device = RemoteDevice(id: 'remote-client', name: deviceName, platform: platform);
|
||||
final device = RemoteDevice(
|
||||
id: 'remote-client',
|
||||
name: deviceName,
|
||||
platform: platform,
|
||||
connectedAt: DateTime.now(),
|
||||
);
|
||||
_deviceConnectedController.add(device);
|
||||
_connectionStateController.add(RemoteSessionStatus.connected);
|
||||
|
||||
@@ -516,7 +521,12 @@ class CompanionRemotePeerService with KeepaliveMixin {
|
||||
completer.complete();
|
||||
}
|
||||
|
||||
final device = RemoteDevice(id: 'host', name: 'Desktop', platform: 'desktop');
|
||||
final device = RemoteDevice(
|
||||
id: 'host',
|
||||
name: 'Desktop',
|
||||
platform: 'desktop',
|
||||
connectedAt: DateTime.now(),
|
||||
);
|
||||
_deviceConnectedController.add(device);
|
||||
_connectionStateController.add(RemoteSessionStatus.connected);
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
/// Maps an enum value to/from its `int` index. Useful for compact wire formats
|
||||
/// (e.g. companion-remote commands) where the over-the-wire size matters and
|
||||
/// new enum cases are always appended.
|
||||
///
|
||||
/// Out-of-range indices on the wire fall back to [_fallback] instead of
|
||||
/// throwing — important for forward-compat with newer clients sending
|
||||
/// commands the host doesn't yet understand.
|
||||
class IndexedEnumConverter<T extends Enum> implements JsonConverter<T, int> {
|
||||
const IndexedEnumConverter(this._values, this._fallback);
|
||||
|
||||
final List<T> _values;
|
||||
final T _fallback;
|
||||
|
||||
@override
|
||||
T fromJson(int json) => json >= 0 && json < _values.length ? _values[json] : _fallback;
|
||||
|
||||
@override
|
||||
int toJson(T object) => object.index;
|
||||
}
|
||||
@@ -1,98 +1,43 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'watch_session.freezed.dart';
|
||||
|
||||
enum SessionRole { host, guest }
|
||||
|
||||
enum ControlMode { hostOnly, anyone }
|
||||
|
||||
enum SessionState { disconnected, connecting, connected, error }
|
||||
|
||||
class Participant {
|
||||
final String peerId;
|
||||
final String displayName;
|
||||
final bool isHost;
|
||||
final Duration lastKnownPosition;
|
||||
final bool isBuffering;
|
||||
|
||||
const Participant({
|
||||
required this.peerId,
|
||||
required this.displayName,
|
||||
required this.isHost,
|
||||
this.lastKnownPosition = Duration.zero,
|
||||
this.isBuffering = false,
|
||||
});
|
||||
|
||||
Participant copyWith({
|
||||
String? peerId,
|
||||
String? displayName,
|
||||
bool? isHost,
|
||||
Duration? lastKnownPosition,
|
||||
bool? isBuffering,
|
||||
}) {
|
||||
return Participant(
|
||||
peerId: peerId ?? this.peerId,
|
||||
displayName: displayName ?? this.displayName,
|
||||
isHost: isHost ?? this.isHost,
|
||||
lastKnownPosition: lastKnownPosition ?? this.lastKnownPosition,
|
||||
isBuffering: isBuffering ?? this.isBuffering,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) || other is Participant && runtimeType == other.runtimeType && peerId == other.peerId;
|
||||
|
||||
@override
|
||||
int get hashCode => peerId.hashCode;
|
||||
@freezed
|
||||
sealed class Participant with _$Participant {
|
||||
const factory Participant({
|
||||
required String peerId,
|
||||
required String displayName,
|
||||
required bool isHost,
|
||||
@Default(Duration.zero) Duration lastKnownPosition,
|
||||
@Default(false) bool isBuffering,
|
||||
}) = _Participant;
|
||||
}
|
||||
|
||||
class WatchSession {
|
||||
final String sessionId;
|
||||
final SessionRole role;
|
||||
final ControlMode controlMode;
|
||||
final SessionState state;
|
||||
final String? errorMessage;
|
||||
final String? mediaRatingKey;
|
||||
final String? mediaServerId;
|
||||
final String? mediaTitle;
|
||||
final String? hostPeerId;
|
||||
@freezed
|
||||
sealed class WatchSession with _$WatchSession {
|
||||
const WatchSession._();
|
||||
|
||||
const WatchSession({
|
||||
required this.sessionId,
|
||||
required this.role,
|
||||
required this.controlMode,
|
||||
required this.state,
|
||||
this.errorMessage,
|
||||
this.mediaRatingKey,
|
||||
this.mediaServerId,
|
||||
this.mediaTitle,
|
||||
this.hostPeerId,
|
||||
});
|
||||
|
||||
bool get isHost => role == SessionRole.host;
|
||||
|
||||
bool get isConnected => state == SessionState.connected;
|
||||
|
||||
WatchSession copyWith({
|
||||
String? sessionId,
|
||||
SessionRole? role,
|
||||
ControlMode? controlMode,
|
||||
SessionState? state,
|
||||
const factory WatchSession({
|
||||
required String sessionId,
|
||||
required SessionRole role,
|
||||
required ControlMode controlMode,
|
||||
required SessionState state,
|
||||
String? errorMessage,
|
||||
String? mediaRatingKey,
|
||||
String? mediaServerId,
|
||||
String? mediaTitle,
|
||||
String? hostPeerId,
|
||||
}) {
|
||||
return WatchSession(
|
||||
sessionId: sessionId ?? this.sessionId,
|
||||
role: role ?? this.role,
|
||||
controlMode: controlMode ?? this.controlMode,
|
||||
state: state ?? this.state,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
mediaRatingKey: mediaRatingKey ?? this.mediaRatingKey,
|
||||
mediaServerId: mediaServerId ?? this.mediaServerId,
|
||||
mediaTitle: mediaTitle ?? this.mediaTitle,
|
||||
hostPeerId: hostPeerId ?? this.hostPeerId,
|
||||
);
|
||||
}
|
||||
}) = _WatchSession;
|
||||
|
||||
bool get isHost => role == SessionRole.host;
|
||||
|
||||
bool get isConnected => state == SessionState.connected;
|
||||
|
||||
/// Create a new session as host
|
||||
factory WatchSession.createAsHost({
|
||||
@@ -102,8 +47,7 @@ class WatchSession {
|
||||
String? mediaRatingKey,
|
||||
String? mediaServerId,
|
||||
String? mediaTitle,
|
||||
}) {
|
||||
return WatchSession(
|
||||
}) => WatchSession(
|
||||
sessionId: sessionId,
|
||||
role: SessionRole.host,
|
||||
controlMode: controlMode,
|
||||
@@ -113,15 +57,12 @@ class WatchSession {
|
||||
mediaServerId: mediaServerId,
|
||||
mediaTitle: mediaTitle,
|
||||
);
|
||||
}
|
||||
|
||||
/// Create a session as guest (joining)
|
||||
factory WatchSession.joinAsGuest({required String sessionId}) {
|
||||
return WatchSession(
|
||||
factory WatchSession.joinAsGuest({required String sessionId}) => WatchSession(
|
||||
sessionId: sessionId,
|
||||
role: SessionRole.guest,
|
||||
controlMode: ControlMode.hostOnly, // Will be updated when connected
|
||||
state: SessionState.connecting,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,552 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'watch_session.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$Participant {
|
||||
|
||||
String get peerId; String get displayName; bool get isHost; Duration get lastKnownPosition; bool get isBuffering;
|
||||
/// Create a copy of Participant
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$ParticipantCopyWith<Participant> get copyWith => _$ParticipantCopyWithImpl<Participant>(this as Participant, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is Participant&&(identical(other.peerId, peerId) || other.peerId == peerId)&&(identical(other.displayName, displayName) || other.displayName == displayName)&&(identical(other.isHost, isHost) || other.isHost == isHost)&&(identical(other.lastKnownPosition, lastKnownPosition) || other.lastKnownPosition == lastKnownPosition)&&(identical(other.isBuffering, isBuffering) || other.isBuffering == isBuffering));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,peerId,displayName,isHost,lastKnownPosition,isBuffering);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Participant(peerId: $peerId, displayName: $displayName, isHost: $isHost, lastKnownPosition: $lastKnownPosition, isBuffering: $isBuffering)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $ParticipantCopyWith<$Res> {
|
||||
factory $ParticipantCopyWith(Participant value, $Res Function(Participant) _then) = _$ParticipantCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String peerId, String displayName, bool isHost, Duration lastKnownPosition, bool isBuffering
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$ParticipantCopyWithImpl<$Res>
|
||||
implements $ParticipantCopyWith<$Res> {
|
||||
_$ParticipantCopyWithImpl(this._self, this._then);
|
||||
|
||||
final Participant _self;
|
||||
final $Res Function(Participant) _then;
|
||||
|
||||
/// Create a copy of Participant
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? peerId = null,Object? displayName = null,Object? isHost = null,Object? lastKnownPosition = null,Object? isBuffering = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
peerId: null == peerId ? _self.peerId : peerId // ignore: cast_nullable_to_non_nullable
|
||||
as String,displayName: null == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
|
||||
as String,isHost: null == isHost ? _self.isHost : isHost // ignore: cast_nullable_to_non_nullable
|
||||
as bool,lastKnownPosition: null == lastKnownPosition ? _self.lastKnownPosition : lastKnownPosition // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,isBuffering: null == isBuffering ? _self.isBuffering : isBuffering // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [Participant].
|
||||
extension ParticipantPatterns on Participant {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _Participant value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Participant() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _Participant value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Participant():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _Participant value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Participant() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String peerId, String displayName, bool isHost, Duration lastKnownPosition, bool isBuffering)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Participant() when $default != null:
|
||||
return $default(_that.peerId,_that.displayName,_that.isHost,_that.lastKnownPosition,_that.isBuffering);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String peerId, String displayName, bool isHost, Duration lastKnownPosition, bool isBuffering) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Participant():
|
||||
return $default(_that.peerId,_that.displayName,_that.isHost,_that.lastKnownPosition,_that.isBuffering);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String peerId, String displayName, bool isHost, Duration lastKnownPosition, bool isBuffering)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Participant() when $default != null:
|
||||
return $default(_that.peerId,_that.displayName,_that.isHost,_that.lastKnownPosition,_that.isBuffering);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Participant implements Participant {
|
||||
const _Participant({required this.peerId, required this.displayName, required this.isHost, this.lastKnownPosition = Duration.zero, this.isBuffering = false});
|
||||
|
||||
|
||||
@override final String peerId;
|
||||
@override final String displayName;
|
||||
@override final bool isHost;
|
||||
@override@JsonKey() final Duration lastKnownPosition;
|
||||
@override@JsonKey() final bool isBuffering;
|
||||
|
||||
/// Create a copy of Participant
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$ParticipantCopyWith<_Participant> get copyWith => __$ParticipantCopyWithImpl<_Participant>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Participant&&(identical(other.peerId, peerId) || other.peerId == peerId)&&(identical(other.displayName, displayName) || other.displayName == displayName)&&(identical(other.isHost, isHost) || other.isHost == isHost)&&(identical(other.lastKnownPosition, lastKnownPosition) || other.lastKnownPosition == lastKnownPosition)&&(identical(other.isBuffering, isBuffering) || other.isBuffering == isBuffering));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,peerId,displayName,isHost,lastKnownPosition,isBuffering);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Participant(peerId: $peerId, displayName: $displayName, isHost: $isHost, lastKnownPosition: $lastKnownPosition, isBuffering: $isBuffering)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$ParticipantCopyWith<$Res> implements $ParticipantCopyWith<$Res> {
|
||||
factory _$ParticipantCopyWith(_Participant value, $Res Function(_Participant) _then) = __$ParticipantCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String peerId, String displayName, bool isHost, Duration lastKnownPosition, bool isBuffering
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$ParticipantCopyWithImpl<$Res>
|
||||
implements _$ParticipantCopyWith<$Res> {
|
||||
__$ParticipantCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Participant _self;
|
||||
final $Res Function(_Participant) _then;
|
||||
|
||||
/// Create a copy of Participant
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? peerId = null,Object? displayName = null,Object? isHost = null,Object? lastKnownPosition = null,Object? isBuffering = null,}) {
|
||||
return _then(_Participant(
|
||||
peerId: null == peerId ? _self.peerId : peerId // ignore: cast_nullable_to_non_nullable
|
||||
as String,displayName: null == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
|
||||
as String,isHost: null == isHost ? _self.isHost : isHost // ignore: cast_nullable_to_non_nullable
|
||||
as bool,lastKnownPosition: null == lastKnownPosition ? _self.lastKnownPosition : lastKnownPosition // ignore: cast_nullable_to_non_nullable
|
||||
as Duration,isBuffering: null == isBuffering ? _self.isBuffering : isBuffering // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$WatchSession {
|
||||
|
||||
String get sessionId; SessionRole get role; ControlMode get controlMode; SessionState get state; String? get errorMessage; String? get mediaRatingKey; String? get mediaServerId; String? get mediaTitle; String? get hostPeerId;
|
||||
/// Create a copy of WatchSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$WatchSessionCopyWith<WatchSession> get copyWith => _$WatchSessionCopyWithImpl<WatchSession>(this as WatchSession, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is WatchSession&&(identical(other.sessionId, sessionId) || other.sessionId == sessionId)&&(identical(other.role, role) || other.role == role)&&(identical(other.controlMode, controlMode) || other.controlMode == controlMode)&&(identical(other.state, state) || other.state == state)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.mediaRatingKey, mediaRatingKey) || other.mediaRatingKey == mediaRatingKey)&&(identical(other.mediaServerId, mediaServerId) || other.mediaServerId == mediaServerId)&&(identical(other.mediaTitle, mediaTitle) || other.mediaTitle == mediaTitle)&&(identical(other.hostPeerId, hostPeerId) || other.hostPeerId == hostPeerId));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,sessionId,role,controlMode,state,errorMessage,mediaRatingKey,mediaServerId,mediaTitle,hostPeerId);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WatchSession(sessionId: $sessionId, role: $role, controlMode: $controlMode, state: $state, errorMessage: $errorMessage, mediaRatingKey: $mediaRatingKey, mediaServerId: $mediaServerId, mediaTitle: $mediaTitle, hostPeerId: $hostPeerId)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $WatchSessionCopyWith<$Res> {
|
||||
factory $WatchSessionCopyWith(WatchSession value, $Res Function(WatchSession) _then) = _$WatchSessionCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String sessionId, SessionRole role, ControlMode controlMode, SessionState state, String? errorMessage, String? mediaRatingKey, String? mediaServerId, String? mediaTitle, String? hostPeerId
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$WatchSessionCopyWithImpl<$Res>
|
||||
implements $WatchSessionCopyWith<$Res> {
|
||||
_$WatchSessionCopyWithImpl(this._self, this._then);
|
||||
|
||||
final WatchSession _self;
|
||||
final $Res Function(WatchSession) _then;
|
||||
|
||||
/// Create a copy of WatchSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? sessionId = null,Object? role = null,Object? controlMode = null,Object? state = null,Object? errorMessage = freezed,Object? mediaRatingKey = freezed,Object? mediaServerId = freezed,Object? mediaTitle = freezed,Object? hostPeerId = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
sessionId: null == sessionId ? _self.sessionId : sessionId // ignore: cast_nullable_to_non_nullable
|
||||
as String,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
|
||||
as SessionRole,controlMode: null == controlMode ? _self.controlMode : controlMode // ignore: cast_nullable_to_non_nullable
|
||||
as ControlMode,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
as SessionState,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,mediaRatingKey: freezed == mediaRatingKey ? _self.mediaRatingKey : mediaRatingKey // ignore: cast_nullable_to_non_nullable
|
||||
as String?,mediaServerId: freezed == mediaServerId ? _self.mediaServerId : mediaServerId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,mediaTitle: freezed == mediaTitle ? _self.mediaTitle : mediaTitle // ignore: cast_nullable_to_non_nullable
|
||||
as String?,hostPeerId: freezed == hostPeerId ? _self.hostPeerId : hostPeerId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [WatchSession].
|
||||
extension WatchSessionPatterns on WatchSession {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _WatchSession value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _WatchSession() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _WatchSession value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _WatchSession():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _WatchSession value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _WatchSession() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String sessionId, SessionRole role, ControlMode controlMode, SessionState state, String? errorMessage, String? mediaRatingKey, String? mediaServerId, String? mediaTitle, String? hostPeerId)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WatchSession() when $default != null:
|
||||
return $default(_that.sessionId,_that.role,_that.controlMode,_that.state,_that.errorMessage,_that.mediaRatingKey,_that.mediaServerId,_that.mediaTitle,_that.hostPeerId);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String sessionId, SessionRole role, ControlMode controlMode, SessionState state, String? errorMessage, String? mediaRatingKey, String? mediaServerId, String? mediaTitle, String? hostPeerId) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WatchSession():
|
||||
return $default(_that.sessionId,_that.role,_that.controlMode,_that.state,_that.errorMessage,_that.mediaRatingKey,_that.mediaServerId,_that.mediaTitle,_that.hostPeerId);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String sessionId, SessionRole role, ControlMode controlMode, SessionState state, String? errorMessage, String? mediaRatingKey, String? mediaServerId, String? mediaTitle, String? hostPeerId)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _WatchSession() when $default != null:
|
||||
return $default(_that.sessionId,_that.role,_that.controlMode,_that.state,_that.errorMessage,_that.mediaRatingKey,_that.mediaServerId,_that.mediaTitle,_that.hostPeerId);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _WatchSession extends WatchSession {
|
||||
const _WatchSession({required this.sessionId, required this.role, required this.controlMode, required this.state, this.errorMessage, this.mediaRatingKey, this.mediaServerId, this.mediaTitle, this.hostPeerId}): super._();
|
||||
|
||||
|
||||
@override final String sessionId;
|
||||
@override final SessionRole role;
|
||||
@override final ControlMode controlMode;
|
||||
@override final SessionState state;
|
||||
@override final String? errorMessage;
|
||||
@override final String? mediaRatingKey;
|
||||
@override final String? mediaServerId;
|
||||
@override final String? mediaTitle;
|
||||
@override final String? hostPeerId;
|
||||
|
||||
/// Create a copy of WatchSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$WatchSessionCopyWith<_WatchSession> get copyWith => __$WatchSessionCopyWithImpl<_WatchSession>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WatchSession&&(identical(other.sessionId, sessionId) || other.sessionId == sessionId)&&(identical(other.role, role) || other.role == role)&&(identical(other.controlMode, controlMode) || other.controlMode == controlMode)&&(identical(other.state, state) || other.state == state)&&(identical(other.errorMessage, errorMessage) || other.errorMessage == errorMessage)&&(identical(other.mediaRatingKey, mediaRatingKey) || other.mediaRatingKey == mediaRatingKey)&&(identical(other.mediaServerId, mediaServerId) || other.mediaServerId == mediaServerId)&&(identical(other.mediaTitle, mediaTitle) || other.mediaTitle == mediaTitle)&&(identical(other.hostPeerId, hostPeerId) || other.hostPeerId == hostPeerId));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,sessionId,role,controlMode,state,errorMessage,mediaRatingKey,mediaServerId,mediaTitle,hostPeerId);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WatchSession(sessionId: $sessionId, role: $role, controlMode: $controlMode, state: $state, errorMessage: $errorMessage, mediaRatingKey: $mediaRatingKey, mediaServerId: $mediaServerId, mediaTitle: $mediaTitle, hostPeerId: $hostPeerId)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$WatchSessionCopyWith<$Res> implements $WatchSessionCopyWith<$Res> {
|
||||
factory _$WatchSessionCopyWith(_WatchSession value, $Res Function(_WatchSession) _then) = __$WatchSessionCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String sessionId, SessionRole role, ControlMode controlMode, SessionState state, String? errorMessage, String? mediaRatingKey, String? mediaServerId, String? mediaTitle, String? hostPeerId
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$WatchSessionCopyWithImpl<$Res>
|
||||
implements _$WatchSessionCopyWith<$Res> {
|
||||
__$WatchSessionCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _WatchSession _self;
|
||||
final $Res Function(_WatchSession) _then;
|
||||
|
||||
/// Create a copy of WatchSession
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? sessionId = null,Object? role = null,Object? controlMode = null,Object? state = null,Object? errorMessage = freezed,Object? mediaRatingKey = freezed,Object? mediaServerId = freezed,Object? mediaTitle = freezed,Object? hostPeerId = freezed,}) {
|
||||
return _then(_WatchSession(
|
||||
sessionId: null == sessionId ? _self.sessionId : sessionId // ignore: cast_nullable_to_non_nullable
|
||||
as String,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
|
||||
as SessionRole,controlMode: null == controlMode ? _self.controlMode : controlMode // ignore: cast_nullable_to_non_nullable
|
||||
as ControlMode,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
as SessionState,errorMessage: freezed == errorMessage ? _self.errorMessage : errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String?,mediaRatingKey: freezed == mediaRatingKey ? _self.mediaRatingKey : mediaRatingKey // ignore: cast_nullable_to_non_nullable
|
||||
as String?,mediaServerId: freezed == mediaServerId ? _self.mediaServerId : mediaServerId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,mediaTitle: freezed == mediaTitle ? _self.mediaTitle : mediaTitle // ignore: cast_nullable_to_non_nullable
|
||||
as String?,hostPeerId: freezed == hostPeerId ? _self.hostPeerId : hostPeerId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -544,7 +544,7 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
if (message.peerId != null && message.position != null) {
|
||||
final index = _participants.indexWhere((p) => p.peerId == message.peerId);
|
||||
if (index >= 0) {
|
||||
_participants[index] = _participants[index].copyWith(lastKnownPosition: message.position);
|
||||
_participants[index] = _participants[index].copyWith(lastKnownPosition: message.position!);
|
||||
// Don't notify for position updates - too frequent
|
||||
}
|
||||
}
|
||||
@@ -606,7 +606,7 @@ class WatchTogetherProvider with ChangeNotifier {
|
||||
|
||||
if (message.controlMode != null) {
|
||||
appLogger.d('WatchTogether: Received session config, controlMode: ${message.controlMode}');
|
||||
_session = _session!.copyWith(controlMode: message.controlMode);
|
||||
_session = _session!.copyWith(controlMode: message.controlMode!);
|
||||
_syncManager?.updateSession(_session!); // Update sync manager if it exists
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
+21
-1
@@ -59,7 +59,27 @@ else
|
||||
rm -f "$out"
|
||||
fi
|
||||
|
||||
# 2. Native formatting
|
||||
# 2. Codegen freshness (build_runner outputs newer than their sources)
|
||||
section "codegen freshness"
|
||||
stale=()
|
||||
while IFS= read -r -d '' src; do
|
||||
for gen in "${src%.dart}.g.dart" "${src%.dart}.freezed.dart"; do
|
||||
if [ -f "$gen" ] && [ "$src" -nt "$gen" ]; then
|
||||
stale+=("${src#./}")
|
||||
break
|
||||
fi
|
||||
done
|
||||
done < <(find lib -name "*.dart" ! -name "*.g.dart" ! -name "*.freezed.dart" -type f -print0 2>/dev/null)
|
||||
if [ ${#stale[@]} -eq 0 ]; then
|
||||
ok "no stale generated files"
|
||||
else
|
||||
fail "${#stale[@]} dart source(s) newer than their generated .g/.freezed:"
|
||||
printf ' %s\n' "${stale[@]}"
|
||||
echo " Run: scripts/codegen.sh"
|
||||
FAILED=1
|
||||
fi
|
||||
|
||||
# 3. Native formatting
|
||||
section "native format"
|
||||
out="$(mktemp)"
|
||||
if scripts/format_native.sh --check >"$out" 2>&1; then
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
||||
exec dart run build_runner build --delete-conflicting-outputs "$@"
|
||||
@@ -59,13 +59,19 @@ void main() {
|
||||
});
|
||||
|
||||
group('MediaSort equality & hashCode', () {
|
||||
test('equality is based on key only (matches current contract)', () {
|
||||
test('value equality across all fields', () {
|
||||
final a = MediaSort(key: 'k', descKey: 'k:desc', title: 'A', defaultDirection: 'asc');
|
||||
final b = MediaSort(key: 'k', descKey: 'other', title: 'B', defaultDirection: 'desc');
|
||||
final b = MediaSort(key: 'k', descKey: 'k:desc', title: 'A', defaultDirection: 'asc');
|
||||
expect(a, equals(b));
|
||||
expect(a.hashCode, b.hashCode);
|
||||
});
|
||||
|
||||
test('differing non-key fields make instances unequal', () {
|
||||
final a = MediaSort(key: 'k', descKey: 'k:desc', title: 'A', defaultDirection: 'asc');
|
||||
final b = MediaSort(key: 'k', descKey: 'other', title: 'B', defaultDirection: 'desc');
|
||||
expect(a, isNot(equals(b)));
|
||||
});
|
||||
|
||||
test('different keys are not equal', () {
|
||||
final a = MediaSort(key: 'k1', title: 'A');
|
||||
final b = MediaSort(key: 'k2', title: 'A');
|
||||
|
||||
@@ -71,7 +71,7 @@ void main() {
|
||||
});
|
||||
|
||||
Future<Profile> createActiveLocalProfile(String id) async {
|
||||
final profile = Profile(id: id, kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
final profile = Profile.local(id: id, displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
await profiles.upsert(profile);
|
||||
await storage.setActiveProfileId(profile.id);
|
||||
await activeProfile.initialize();
|
||||
@@ -79,12 +79,7 @@ void main() {
|
||||
}
|
||||
|
||||
test('local profile with no connections binds successfully with empty visibility', () async {
|
||||
final profile = Profile(
|
||||
id: 'local-owner',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-owner', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
await profiles.upsert(profile);
|
||||
await storage.setActiveProfileId(profile.id);
|
||||
await activeProfile.initialize();
|
||||
@@ -97,12 +92,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('started binder does not loop forever after empty local bind', () async {
|
||||
final profile = Profile(
|
||||
id: 'local-empty',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Empty',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-empty', displayName: 'Empty', createdAt: DateTime(2026, 1, 1));
|
||||
await profiles.upsert(profile);
|
||||
await storage.setActiveProfileId(profile.id);
|
||||
await activeProfile.initialize();
|
||||
|
||||
@@ -97,9 +97,7 @@ void main() {
|
||||
// Fresh state: no auto-fallback to the first profile so the UI can
|
||||
// force the picker. The binder skips its rebind while active is null,
|
||||
// which is what avoids the surprise PIN prompt at first sign-in.
|
||||
await registry.upsert(
|
||||
Profile(id: 'p1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1)));
|
||||
await provider.initialize();
|
||||
expect(provider.profiles, hasLength(1));
|
||||
expect(provider.activeId, isNull);
|
||||
@@ -127,9 +125,7 @@ void main() {
|
||||
test('initialize clears storage when stored id is stale', () async {
|
||||
// A previously-active profile that was deleted should not keep
|
||||
// storage-scoped settings under the removed profile id.
|
||||
await registry.upsert(
|
||||
Profile(id: 'p1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1)));
|
||||
await storage.setActiveProfileId('ghost-id-no-longer-exists');
|
||||
await provider.initialize();
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
@@ -138,24 +134,16 @@ void main() {
|
||||
});
|
||||
|
||||
test('initialize resolves the stored active profile id', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'p1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(
|
||||
Profile(id: 'p2', kind: ProfileKind.local, displayName: 'Kids', createdAt: DateTime(2026, 1, 2)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1)));
|
||||
await registry.upsert(Profile.local(id: 'p2', displayName: 'Kids', createdAt: DateTime(2026, 1, 2)));
|
||||
await storage.setActiveProfileId('p2');
|
||||
await provider.initialize();
|
||||
expect(provider.activeId, 'p2');
|
||||
});
|
||||
|
||||
test('activate without PIN switches a non-protected profile', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'p1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(
|
||||
Profile(id: 'p2', kind: ProfileKind.local, displayName: 'Kids', createdAt: DateTime(2026, 1, 2)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1)));
|
||||
await registry.upsert(Profile.local(id: 'p2', displayName: 'Kids', createdAt: DateTime(2026, 1, 2)));
|
||||
await provider.initialize();
|
||||
final p2 = provider.profiles.firstWhere((p) => p.id == 'p2');
|
||||
final ok = await provider.activate(p2);
|
||||
@@ -164,9 +152,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('clearActiveProfile clears storage and in-memory active profile', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'p1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1)));
|
||||
await provider.initialize();
|
||||
await provider.activate(provider.profiles.single);
|
||||
|
||||
@@ -178,13 +164,7 @@ void main() {
|
||||
|
||||
test('activate rejects wrong PIN for a protected local profile', () async {
|
||||
await registry.upsert(
|
||||
Profile(
|
||||
id: 'p1',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Kids',
|
||||
pinHash: computePinHash('1234'),
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
),
|
||||
Profile.local(id: 'p1', displayName: 'Kids', pinHash: computePinHash('1234'), createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await provider.initialize();
|
||||
final p1 = provider.profiles.first;
|
||||
@@ -193,9 +173,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('hasMultipleProfiles reflects the registry size', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'p1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1)));
|
||||
await provider.initialize();
|
||||
expect(provider.hasMultipleProfiles, isFalse);
|
||||
// Latch onto the next provider notification that flips the flag,
|
||||
@@ -211,9 +189,7 @@ void main() {
|
||||
|
||||
provider.addListener(listener);
|
||||
addTearDown(() => provider.removeListener(listener));
|
||||
await registry.upsert(
|
||||
Profile(id: 'p2', kind: ProfileKind.local, displayName: 'Kids', createdAt: DateTime(2026, 1, 2)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p2', displayName: 'Kids', createdAt: DateTime(2026, 1, 2)));
|
||||
await flipped.future.timeout(const Duration(seconds: 2));
|
||||
expect(provider.hasMultipleProfiles, isTrue);
|
||||
});
|
||||
|
||||
@@ -23,9 +23,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('upsert + get round-trips a local profile', () async {
|
||||
final profile = Profile(
|
||||
final profile = Profile.local(
|
||||
id: 'local-1',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
pinHash: computePinHash('1234'),
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
@@ -40,9 +39,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('upsert + get round-trips a plex_home profile', () async {
|
||||
final profile = Profile(
|
||||
final profile = Profile.plexHome(
|
||||
id: 'plex-home-acct-uuid',
|
||||
kind: ProfileKind.plexHome,
|
||||
displayName: 'Admin',
|
||||
avatarThumbUrl: 'https://plex.tv/users/abc/avatar?',
|
||||
parentConnectionId: 'acct',
|
||||
@@ -62,28 +60,20 @@ void main() {
|
||||
});
|
||||
|
||||
test('list orders by sortOrder then createdAt', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'a', kind: ProfileKind.local, displayName: 'A', sortOrder: 1, createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(
|
||||
Profile(id: 'b', kind: ProfileKind.local, displayName: 'B', sortOrder: 0, createdAt: DateTime(2026, 1, 2)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'a', displayName: 'A', sortOrder: 1, createdAt: DateTime(2026, 1, 1)));
|
||||
await registry.upsert(Profile.local(id: 'b', displayName: 'B', sortOrder: 0, createdAt: DateTime(2026, 1, 2)));
|
||||
final list = await registry.list();
|
||||
expect(list.map((p) => p.id).toList(), ['b', 'a']);
|
||||
});
|
||||
|
||||
test('remove deletes a profile', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'p', kind: ProfileKind.local, displayName: 'P', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p', displayName: 'P', createdAt: DateTime(2026, 1, 1)));
|
||||
await registry.remove('p');
|
||||
expect(await registry.get('p'), isNull);
|
||||
});
|
||||
|
||||
test('markUsed updates lastUsedAt', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'p', kind: ProfileKind.local, displayName: 'P', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p', displayName: 'P', createdAt: DateTime(2026, 1, 1)));
|
||||
final ts = DateTime(2026, 1, 5, 12, 0);
|
||||
await registry.markUsed('p', ts);
|
||||
final fetched = await registry.get('p');
|
||||
@@ -91,12 +81,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('upsert is idempotent (replaces existing row)', () async {
|
||||
await registry.upsert(
|
||||
Profile(id: 'p', kind: ProfileKind.local, displayName: 'Original', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(
|
||||
Profile(id: 'p', kind: ProfileKind.local, displayName: 'Renamed', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p', displayName: 'Original', createdAt: DateTime(2026, 1, 1)));
|
||||
await registry.upsert(Profile.local(id: 'p', displayName: 'Renamed', createdAt: DateTime(2026, 1, 1)));
|
||||
final fetched = await registry.get('p');
|
||||
expect(fetched!.displayName, 'Renamed');
|
||||
});
|
||||
@@ -115,9 +101,7 @@ void main() {
|
||||
emitsThrough(isEmpty),
|
||||
]),
|
||||
);
|
||||
await registry.upsert(
|
||||
Profile(id: 'p', kind: ProfileKind.local, displayName: 'P', createdAt: DateTime(2026, 1, 1)),
|
||||
);
|
||||
await registry.upsert(Profile.local(id: 'p', displayName: 'P', createdAt: DateTime(2026, 1, 1)));
|
||||
await registry.remove('p');
|
||||
await assertion;
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:plezy/profiles/profile.dart';
|
||||
void main() {
|
||||
group('Profile', () {
|
||||
test('local profile defaults', () {
|
||||
final p = Profile(id: 'local-1', kind: ProfileKind.local, displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
final p = Profile.local(id: 'local-1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
expect(p.isLocal, isTrue);
|
||||
expect(p.isPlexHome, isFalse);
|
||||
expect(p.isPinProtected, isFalse);
|
||||
@@ -12,9 +12,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('local profile with PIN is pin-protected', () {
|
||||
final p = Profile(
|
||||
final p = Profile.local(
|
||||
id: 'local-1',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Kids',
|
||||
pinHash: computePinHash('1234'),
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
@@ -23,9 +22,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('plex_home profile pin protection follows the protected flag', () {
|
||||
final p = Profile(
|
||||
final p = Profile.plexHome(
|
||||
id: 'plex-home-acct1-uuid1',
|
||||
kind: ProfileKind.plexHome,
|
||||
displayName: 'Sarah',
|
||||
parentConnectionId: 'acct1',
|
||||
plexProtected: true,
|
||||
@@ -36,9 +34,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('local PIN hash is round-tripped via configJson', () {
|
||||
final p = Profile(
|
||||
final p = Profile.local(
|
||||
id: 'local-1',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Kids',
|
||||
pinHash: computePinHash('1234'),
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
@@ -59,9 +56,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('plex_home configJson round-trips with all flags', () {
|
||||
final p = Profile(
|
||||
final p = Profile.plexHome(
|
||||
id: 'plex-home-acct1-uuid1',
|
||||
kind: ProfileKind.plexHome,
|
||||
displayName: 'Admin',
|
||||
parentConnectionId: 'acct1',
|
||||
plexAdmin: true,
|
||||
|
||||
@@ -6,12 +6,7 @@ import 'package:plezy/profiles/profiles_view.dart';
|
||||
void main() {
|
||||
group('visibleProfileConnections', () {
|
||||
test('keeps all local profile connection rows', () {
|
||||
final profile = Profile(
|
||||
id: 'local-1',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-1', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
const rows = [
|
||||
ProfileConnection(profileId: 'local-1', connectionId: 'plex-1', userIdentifier: 'u1'),
|
||||
ProfileConnection(profileId: 'local-1', connectionId: 'jellyfin-1', userIdentifier: 'u2'),
|
||||
@@ -21,9 +16,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('filters Plex Home parent token cache row', () {
|
||||
final profile = Profile(
|
||||
final profile = Profile.plexHome(
|
||||
id: 'plex-home-plex-1-user-1',
|
||||
kind: ProfileKind.plexHome,
|
||||
displayName: 'Kid',
|
||||
parentConnectionId: 'plex-1',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
|
||||
@@ -461,7 +461,7 @@ JellyfinConnection _jellyfinConnection(String id) {
|
||||
}
|
||||
|
||||
Profile _localProfile(String id) {
|
||||
return Profile(id: id, kind: ProfileKind.local, displayName: id, createdAt: DateTime(2026, 1, 1));
|
||||
return Profile.local(id: id, displayName: id, createdAt: DateTime(2026, 1, 1));
|
||||
}
|
||||
|
||||
PlexHome _home(String adminUuid) {
|
||||
|
||||
@@ -80,12 +80,7 @@ void main() {
|
||||
await db.close();
|
||||
});
|
||||
|
||||
final profile = Profile(
|
||||
id: 'local-owner',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-owner', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
final plex = PlexAccountConnection(
|
||||
id: 'plex-a',
|
||||
accountToken: 'plex-token',
|
||||
@@ -217,12 +212,7 @@ void main() {
|
||||
await db.close();
|
||||
});
|
||||
|
||||
final profile = Profile(
|
||||
id: 'local-owner',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-owner', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
final accountA = PlexAccountConnection(
|
||||
id: 'plex-a',
|
||||
accountToken: 'wrong-owner-token',
|
||||
|
||||
@@ -75,12 +75,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('initial profile selection is skipped when a profile was auto-selected', () {
|
||||
final profile = Profile(
|
||||
id: 'local-owner',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-owner', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
|
||||
expect(
|
||||
shouldPromptForInitialProfileSelection(
|
||||
@@ -94,12 +89,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('initial profile selection is required when the launch setting is enabled', () {
|
||||
final profile = Profile(
|
||||
id: 'local-owner',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-owner', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
|
||||
expect(
|
||||
shouldPromptForInitialProfileSelection(
|
||||
|
||||
@@ -35,12 +35,7 @@ void main() {
|
||||
testWidgets('remote back pops the manage profile page', (tester) async {
|
||||
TvDetectionService.debugSetAppleTVOverride(true);
|
||||
final db = AppDatabase.forTesting(NativeDatabase.memory());
|
||||
final profile = Profile(
|
||||
id: 'local-owner',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-owner', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
final profiles = ProfileRegistry(db);
|
||||
final connections = _FakeConnectionRegistry(db);
|
||||
final profileConnections = _FakeProfileConnectionRegistry(db);
|
||||
|
||||
@@ -28,12 +28,7 @@ void main() {
|
||||
|
||||
testWidgets('D-pad can focus profile actions and open the manage menu', (tester) async {
|
||||
final db = AppDatabase.forTesting(NativeDatabase.memory());
|
||||
final profile = Profile(
|
||||
id: 'local-owner',
|
||||
kind: ProfileKind.local,
|
||||
displayName: 'Owner',
|
||||
createdAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final profile = Profile.local(id: 'local-owner', displayName: 'Owner', createdAt: DateTime(2026, 1, 1));
|
||||
final profiles = _FakeProfileRegistry(db, [profile]);
|
||||
final connections = _FakeConnectionRegistry(db);
|
||||
final profileConnections = _FakeProfileConnectionRegistry(db);
|
||||
|
||||
@@ -5,13 +5,8 @@ import 'package:plezy/profiles/profile.dart';
|
||||
import 'package:plezy/screens/settings/add_jellyfin_screen.dart';
|
||||
import 'package:plezy/utils/platform_detector.dart';
|
||||
|
||||
Profile _profile(String id) => Profile(
|
||||
id: id,
|
||||
kind: ProfileKind.local,
|
||||
displayName: id,
|
||||
sortOrder: 0,
|
||||
createdAt: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
);
|
||||
Profile _profile(String id) =>
|
||||
Profile.local(id: id, displayName: id, sortOrder: 0, createdAt: DateTime.fromMillisecondsSinceEpoch(0));
|
||||
|
||||
void main() {
|
||||
tearDown(() {
|
||||
|
||||
Reference in New Issue
Block a user