feat: Integrate the AniList API since Jikan is shutting down
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:anitrack/i18n/strings.g.dart';
|
||||
import 'package:anitrack/src/service/anilist/anilist_client.dart';
|
||||
import 'package:anitrack/src/service/database.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_search_bloc.dart';
|
||||
@@ -35,6 +36,7 @@ void main() async {
|
||||
GetIt.I.registerSingleton<NavigationBloc>(NavigationBloc(navKey));
|
||||
GetIt.I.registerSingleton<SettingsBloc>(SettingsBloc());
|
||||
GetIt.I.registerSingleton<CalendarBloc>(CalendarBloc());
|
||||
GetIt.I.registerSingleton<AniListClient>(AniListClient());
|
||||
|
||||
// Load animes
|
||||
GetIt.I.get<AnimeListBloc>().add(
|
||||
|
||||
39416
lib/oss_licenses.dart
Normal file
39416
lib/oss_licenses.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
import 'package:anitrack/src/data/source.dart';
|
||||
import 'package:anitrack/src/data/type.dart';
|
||||
import 'package:anitrack/src/service/database.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@@ -42,6 +43,9 @@ abstract class AnimeTrackingData with _$AnimeTrackingData, TrackingMedium {
|
||||
|
||||
/// The day of the week the anime is airing
|
||||
String? broadcastDay,
|
||||
|
||||
/// The source where we got the data from.
|
||||
@TrackingDataSourceConverter() TrackingDataSource source,
|
||||
) = _AnimeTrackingData;
|
||||
|
||||
AnimeTrackingData._();
|
||||
|
||||
@@ -23,7 +23,8 @@ mixin _$AnimeTrackingData {
|
||||
int? get episodesTotal;/// URL to the thumbnail/cover art for the anime.
|
||||
String get thumbnailUrl;/// Flag whether the anime is airing
|
||||
@BoolConverter() bool get airing;/// The day of the week the anime is airing
|
||||
String? get broadcastDay;
|
||||
String? get broadcastDay;/// The source where we got the data from.
|
||||
@TrackingDataSourceConverter() TrackingDataSource get source;
|
||||
/// Create a copy of AnimeTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -36,16 +37,16 @@ $AnimeTrackingDataCopyWith<AnimeTrackingData> get copyWith => _$AnimeTrackingDat
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AnimeTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.episodesWatched, episodesWatched) || other.episodesWatched == episodesWatched)&&(identical(other.episodesTotal, episodesTotal) || other.episodesTotal == episodesTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl)&&(identical(other.airing, airing) || other.airing == airing)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AnimeTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.episodesWatched, episodesWatched) || other.episodesWatched == episodesWatched)&&(identical(other.episodesTotal, episodesTotal) || other.episodesTotal == episodesTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl)&&(identical(other.airing, airing) || other.airing == airing)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay)&&(identical(other.source, source) || other.source == source));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,episodesWatched,episodesTotal,thumbnailUrl,airing,broadcastDay);
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,episodesWatched,episodesTotal,thumbnailUrl,airing,broadcastDay,source);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AnimeTrackingData(id: $id, state: $state, title: $title, episodesWatched: $episodesWatched, episodesTotal: $episodesTotal, thumbnailUrl: $thumbnailUrl, airing: $airing, broadcastDay: $broadcastDay)';
|
||||
return 'AnimeTrackingData(id: $id, state: $state, title: $title, episodesWatched: $episodesWatched, episodesTotal: $episodesTotal, thumbnailUrl: $thumbnailUrl, airing: $airing, broadcastDay: $broadcastDay, source: $source)';
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +57,7 @@ abstract mixin class $AnimeTrackingDataCopyWith<$Res> {
|
||||
factory $AnimeTrackingDataCopyWith(AnimeTrackingData value, $Res Function(AnimeTrackingData) _then) = _$AnimeTrackingDataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl,@BoolConverter() bool airing, String? broadcastDay
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl,@BoolConverter() bool airing, String? broadcastDay,@TrackingDataSourceConverter() TrackingDataSource source
|
||||
});
|
||||
|
||||
|
||||
@@ -73,7 +74,7 @@ class _$AnimeTrackingDataCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of AnimeTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? state = null,Object? title = null,Object? episodesWatched = null,Object? episodesTotal = freezed,Object? thumbnailUrl = null,Object? airing = null,Object? broadcastDay = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? state = null,Object? title = null,Object? episodesWatched = null,Object? episodesTotal = freezed,Object? thumbnailUrl = null,Object? airing = null,Object? broadcastDay = freezed,Object? source = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
@@ -83,7 +84,8 @@ as int,episodesTotal: freezed == episodesTotal ? _self.episodesTotal : episodesT
|
||||
as int?,thumbnailUrl: null == thumbnailUrl ? _self.thumbnailUrl : thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,airing: null == airing ? _self.airing : airing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,broadcastDay: freezed == broadcastDay ? _self.broadcastDay : broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
as String?,source: null == source ? _self.source : source // ignore: cast_nullable_to_non_nullable
|
||||
as TrackingDataSource,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -168,10 +170,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl, @BoolConverter() bool airing, String? broadcastDay)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl, @BoolConverter() bool airing, String? broadcastDay, @TrackingDataSourceConverter() TrackingDataSource source)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeTrackingData() when $default != null:
|
||||
return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.episodesTotal,_that.thumbnailUrl,_that.airing,_that.broadcastDay);case _:
|
||||
return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.episodesTotal,_that.thumbnailUrl,_that.airing,_that.broadcastDay,_that.source);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -189,10 +191,10 @@ return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.epi
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl, @BoolConverter() bool airing, String? broadcastDay) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl, @BoolConverter() bool airing, String? broadcastDay, @TrackingDataSourceConverter() TrackingDataSource source) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeTrackingData():
|
||||
return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.episodesTotal,_that.thumbnailUrl,_that.airing,_that.broadcastDay);case _:
|
||||
return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.episodesTotal,_that.thumbnailUrl,_that.airing,_that.broadcastDay,_that.source);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -209,10 +211,10 @@ return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.epi
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl, @BoolConverter() bool airing, String? broadcastDay)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl, @BoolConverter() bool airing, String? broadcastDay, @TrackingDataSourceConverter() TrackingDataSource source)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeTrackingData() when $default != null:
|
||||
return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.episodesTotal,_that.thumbnailUrl,_that.airing,_that.broadcastDay);case _:
|
||||
return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.episodesTotal,_that.thumbnailUrl,_that.airing,_that.broadcastDay,_that.source);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -224,7 +226,7 @@ return $default(_that.id,_that.state,_that.title,_that.episodesWatched,_that.epi
|
||||
@JsonSerializable()
|
||||
|
||||
class _AnimeTrackingData extends AnimeTrackingData {
|
||||
_AnimeTrackingData(this.id, @MediumTrackingStateConverter() this.state, this.title, this.episodesWatched, this.episodesTotal, this.thumbnailUrl, @BoolConverter() this.airing, this.broadcastDay): super._();
|
||||
_AnimeTrackingData(this.id, @MediumTrackingStateConverter() this.state, this.title, this.episodesWatched, this.episodesTotal, this.thumbnailUrl, @BoolConverter() this.airing, this.broadcastDay, @TrackingDataSourceConverter() this.source): super._();
|
||||
factory _AnimeTrackingData.fromJson(Map<String, dynamic> json) => _$AnimeTrackingDataFromJson(json);
|
||||
|
||||
/// The ID of the anime
|
||||
@@ -243,6 +245,8 @@ class _AnimeTrackingData extends AnimeTrackingData {
|
||||
@override@BoolConverter() final bool airing;
|
||||
/// The day of the week the anime is airing
|
||||
@override final String? broadcastDay;
|
||||
/// The source where we got the data from.
|
||||
@override@TrackingDataSourceConverter() final TrackingDataSource source;
|
||||
|
||||
/// Create a copy of AnimeTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -257,16 +261,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AnimeTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.episodesWatched, episodesWatched) || other.episodesWatched == episodesWatched)&&(identical(other.episodesTotal, episodesTotal) || other.episodesTotal == episodesTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl)&&(identical(other.airing, airing) || other.airing == airing)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AnimeTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.episodesWatched, episodesWatched) || other.episodesWatched == episodesWatched)&&(identical(other.episodesTotal, episodesTotal) || other.episodesTotal == episodesTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl)&&(identical(other.airing, airing) || other.airing == airing)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay)&&(identical(other.source, source) || other.source == source));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,episodesWatched,episodesTotal,thumbnailUrl,airing,broadcastDay);
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,episodesWatched,episodesTotal,thumbnailUrl,airing,broadcastDay,source);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AnimeTrackingData(id: $id, state: $state, title: $title, episodesWatched: $episodesWatched, episodesTotal: $episodesTotal, thumbnailUrl: $thumbnailUrl, airing: $airing, broadcastDay: $broadcastDay)';
|
||||
return 'AnimeTrackingData(id: $id, state: $state, title: $title, episodesWatched: $episodesWatched, episodesTotal: $episodesTotal, thumbnailUrl: $thumbnailUrl, airing: $airing, broadcastDay: $broadcastDay, source: $source)';
|
||||
}
|
||||
|
||||
|
||||
@@ -277,7 +281,7 @@ abstract mixin class _$AnimeTrackingDataCopyWith<$Res> implements $AnimeTracking
|
||||
factory _$AnimeTrackingDataCopyWith(_AnimeTrackingData value, $Res Function(_AnimeTrackingData) _then) = __$AnimeTrackingDataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl,@BoolConverter() bool airing, String? broadcastDay
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int episodesWatched, int? episodesTotal, String thumbnailUrl,@BoolConverter() bool airing, String? broadcastDay,@TrackingDataSourceConverter() TrackingDataSource source
|
||||
});
|
||||
|
||||
|
||||
@@ -294,7 +298,7 @@ class __$AnimeTrackingDataCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of AnimeTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? state = null,Object? title = null,Object? episodesWatched = null,Object? episodesTotal = freezed,Object? thumbnailUrl = null,Object? airing = null,Object? broadcastDay = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? state = null,Object? title = null,Object? episodesWatched = null,Object? episodesTotal = freezed,Object? thumbnailUrl = null,Object? airing = null,Object? broadcastDay = freezed,Object? source = null,}) {
|
||||
return _then(_AnimeTrackingData(
|
||||
null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
@@ -304,7 +308,8 @@ as int,freezed == episodesTotal ? _self.episodesTotal : episodesTotal // ignore:
|
||||
as int?,null == thumbnailUrl ? _self.thumbnailUrl : thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,null == airing ? _self.airing : airing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,freezed == broadcastDay ? _self.broadcastDay : broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
as String?,null == source ? _self.source : source // ignore: cast_nullable_to_non_nullable
|
||||
as TrackingDataSource,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ _AnimeTrackingData _$AnimeTrackingDataFromJson(Map<String, dynamic> json) =>
|
||||
json['thumbnailUrl'] as String,
|
||||
const BoolConverter().fromJson((json['airing'] as num).toInt()),
|
||||
json['broadcastDay'] as String?,
|
||||
const TrackingDataSourceConverter().fromJson(json['source'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AnimeTrackingDataToJson(_AnimeTrackingData instance) =>
|
||||
@@ -30,4 +31,5 @@ Map<String, dynamic> _$AnimeTrackingDataToJson(_AnimeTrackingData instance) =>
|
||||
'thumbnailUrl': instance.thumbnailUrl,
|
||||
'airing': const BoolConverter().toJson(instance.airing),
|
||||
'broadcastDay': instance.broadcastDay,
|
||||
'source': const TrackingDataSourceConverter().toJson(instance.source),
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:anitrack/src/data/source.dart';
|
||||
import 'package:anitrack/src/data/type.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
@@ -28,6 +29,9 @@ abstract class MangaTrackingData with _$MangaTrackingData, TrackingMedium {
|
||||
|
||||
/// URL to the thumbnail/cover art for the manga.
|
||||
String thumbnailUrl,
|
||||
|
||||
/// The source where we got the data from.
|
||||
@TrackingDataSourceConverter() TrackingDataSource source,
|
||||
) = _MangaTrackingData;
|
||||
|
||||
MangaTrackingData._();
|
||||
|
||||
@@ -22,7 +22,8 @@ mixin _$MangaTrackingData {
|
||||
int get chaptersRead;/// Chapters read.
|
||||
int get volumesOwned;/// Episodes watched.
|
||||
int? get chaptersTotal;/// URL to the thumbnail/cover art for the manga.
|
||||
String get thumbnailUrl;
|
||||
String get thumbnailUrl;/// The source where we got the data from.
|
||||
@TrackingDataSourceConverter() TrackingDataSource get source;
|
||||
/// Create a copy of MangaTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -35,16 +36,16 @@ $MangaTrackingDataCopyWith<MangaTrackingData> get copyWith => _$MangaTrackingDat
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is MangaTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.chaptersRead, chaptersRead) || other.chaptersRead == chaptersRead)&&(identical(other.volumesOwned, volumesOwned) || other.volumesOwned == volumesOwned)&&(identical(other.chaptersTotal, chaptersTotal) || other.chaptersTotal == chaptersTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is MangaTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.chaptersRead, chaptersRead) || other.chaptersRead == chaptersRead)&&(identical(other.volumesOwned, volumesOwned) || other.volumesOwned == volumesOwned)&&(identical(other.chaptersTotal, chaptersTotal) || other.chaptersTotal == chaptersTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl)&&(identical(other.source, source) || other.source == source));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,chaptersRead,volumesOwned,chaptersTotal,thumbnailUrl);
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,chaptersRead,volumesOwned,chaptersTotal,thumbnailUrl,source);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MangaTrackingData(id: $id, state: $state, title: $title, chaptersRead: $chaptersRead, volumesOwned: $volumesOwned, chaptersTotal: $chaptersTotal, thumbnailUrl: $thumbnailUrl)';
|
||||
return 'MangaTrackingData(id: $id, state: $state, title: $title, chaptersRead: $chaptersRead, volumesOwned: $volumesOwned, chaptersTotal: $chaptersTotal, thumbnailUrl: $thumbnailUrl, source: $source)';
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +56,7 @@ abstract mixin class $MangaTrackingDataCopyWith<$Res> {
|
||||
factory $MangaTrackingDataCopyWith(MangaTrackingData value, $Res Function(MangaTrackingData) _then) = _$MangaTrackingDataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl,@TrackingDataSourceConverter() TrackingDataSource source
|
||||
});
|
||||
|
||||
|
||||
@@ -72,7 +73,7 @@ class _$MangaTrackingDataCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of MangaTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? state = null,Object? title = null,Object? chaptersRead = null,Object? volumesOwned = null,Object? chaptersTotal = freezed,Object? thumbnailUrl = null,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? state = null,Object? title = null,Object? chaptersRead = null,Object? volumesOwned = null,Object? chaptersTotal = freezed,Object? thumbnailUrl = null,Object? source = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,state: null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
@@ -81,7 +82,8 @@ as String,chaptersRead: null == chaptersRead ? _self.chaptersRead : chaptersRead
|
||||
as int,volumesOwned: null == volumesOwned ? _self.volumesOwned : volumesOwned // ignore: cast_nullable_to_non_nullable
|
||||
as int,chaptersTotal: freezed == chaptersTotal ? _self.chaptersTotal : chaptersTotal // ignore: cast_nullable_to_non_nullable
|
||||
as int?,thumbnailUrl: null == thumbnailUrl ? _self.thumbnailUrl : thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String,source: null == source ? _self.source : source // ignore: cast_nullable_to_non_nullable
|
||||
as TrackingDataSource,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -166,10 +168,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl, @TrackingDataSourceConverter() TrackingDataSource source)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaTrackingData() when $default != null:
|
||||
return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volumesOwned,_that.chaptersTotal,_that.thumbnailUrl);case _:
|
||||
return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volumesOwned,_that.chaptersTotal,_that.thumbnailUrl,_that.source);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -187,10 +189,10 @@ return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volume
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl, @TrackingDataSourceConverter() TrackingDataSource source) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaTrackingData():
|
||||
return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volumesOwned,_that.chaptersTotal,_that.thumbnailUrl);case _:
|
||||
return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volumesOwned,_that.chaptersTotal,_that.thumbnailUrl,_that.source);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -207,10 +209,10 @@ return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volume
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, @MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl, @TrackingDataSourceConverter() TrackingDataSource source)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaTrackingData() when $default != null:
|
||||
return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volumesOwned,_that.chaptersTotal,_that.thumbnailUrl);case _:
|
||||
return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volumesOwned,_that.chaptersTotal,_that.thumbnailUrl,_that.source);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -222,7 +224,7 @@ return $default(_that.id,_that.state,_that.title,_that.chaptersRead,_that.volume
|
||||
@JsonSerializable()
|
||||
|
||||
class _MangaTrackingData extends MangaTrackingData {
|
||||
_MangaTrackingData(this.id, @MediumTrackingStateConverter() this.state, this.title, this.chaptersRead, this.volumesOwned, this.chaptersTotal, this.thumbnailUrl): super._();
|
||||
_MangaTrackingData(this.id, @MediumTrackingStateConverter() this.state, this.title, this.chaptersRead, this.volumesOwned, this.chaptersTotal, this.thumbnailUrl, @TrackingDataSourceConverter() this.source): super._();
|
||||
factory _MangaTrackingData.fromJson(Map<String, dynamic> json) => _$MangaTrackingDataFromJson(json);
|
||||
|
||||
/// The ID of the manga
|
||||
@@ -239,6 +241,8 @@ class _MangaTrackingData extends MangaTrackingData {
|
||||
@override final int? chaptersTotal;
|
||||
/// URL to the thumbnail/cover art for the manga.
|
||||
@override final String thumbnailUrl;
|
||||
/// The source where we got the data from.
|
||||
@override@TrackingDataSourceConverter() final TrackingDataSource source;
|
||||
|
||||
/// Create a copy of MangaTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -253,16 +257,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MangaTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.chaptersRead, chaptersRead) || other.chaptersRead == chaptersRead)&&(identical(other.volumesOwned, volumesOwned) || other.volumesOwned == volumesOwned)&&(identical(other.chaptersTotal, chaptersTotal) || other.chaptersTotal == chaptersTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MangaTrackingData&&(identical(other.id, id) || other.id == id)&&(identical(other.state, state) || other.state == state)&&(identical(other.title, title) || other.title == title)&&(identical(other.chaptersRead, chaptersRead) || other.chaptersRead == chaptersRead)&&(identical(other.volumesOwned, volumesOwned) || other.volumesOwned == volumesOwned)&&(identical(other.chaptersTotal, chaptersTotal) || other.chaptersTotal == chaptersTotal)&&(identical(other.thumbnailUrl, thumbnailUrl) || other.thumbnailUrl == thumbnailUrl)&&(identical(other.source, source) || other.source == source));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,chaptersRead,volumesOwned,chaptersTotal,thumbnailUrl);
|
||||
int get hashCode => Object.hash(runtimeType,id,state,title,chaptersRead,volumesOwned,chaptersTotal,thumbnailUrl,source);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MangaTrackingData(id: $id, state: $state, title: $title, chaptersRead: $chaptersRead, volumesOwned: $volumesOwned, chaptersTotal: $chaptersTotal, thumbnailUrl: $thumbnailUrl)';
|
||||
return 'MangaTrackingData(id: $id, state: $state, title: $title, chaptersRead: $chaptersRead, volumesOwned: $volumesOwned, chaptersTotal: $chaptersTotal, thumbnailUrl: $thumbnailUrl, source: $source)';
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +277,7 @@ abstract mixin class _$MangaTrackingDataCopyWith<$Res> implements $MangaTracking
|
||||
factory _$MangaTrackingDataCopyWith(_MangaTrackingData value, $Res Function(_MangaTrackingData) _then) = __$MangaTrackingDataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl
|
||||
String id,@MediumTrackingStateConverter() MediumTrackingState state, String title, int chaptersRead, int volumesOwned, int? chaptersTotal, String thumbnailUrl,@TrackingDataSourceConverter() TrackingDataSource source
|
||||
});
|
||||
|
||||
|
||||
@@ -290,7 +294,7 @@ class __$MangaTrackingDataCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of MangaTrackingData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? state = null,Object? title = null,Object? chaptersRead = null,Object? volumesOwned = null,Object? chaptersTotal = freezed,Object? thumbnailUrl = null,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? state = null,Object? title = null,Object? chaptersRead = null,Object? volumesOwned = null,Object? chaptersTotal = freezed,Object? thumbnailUrl = null,Object? source = null,}) {
|
||||
return _then(_MangaTrackingData(
|
||||
null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,null == state ? _self.state : state // ignore: cast_nullable_to_non_nullable
|
||||
@@ -299,7 +303,8 @@ as String,null == chaptersRead ? _self.chaptersRead : chaptersRead // ignore: ca
|
||||
as int,null == volumesOwned ? _self.volumesOwned : volumesOwned // ignore: cast_nullable_to_non_nullable
|
||||
as int,freezed == chaptersTotal ? _self.chaptersTotal : chaptersTotal // ignore: cast_nullable_to_non_nullable
|
||||
as int?,null == thumbnailUrl ? _self.thumbnailUrl : thumbnailUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
as String,null == source ? _self.source : source // ignore: cast_nullable_to_non_nullable
|
||||
as TrackingDataSource,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ _MangaTrackingData _$MangaTrackingDataFromJson(Map<String, dynamic> json) =>
|
||||
(json['volumesOwned'] as num).toInt(),
|
||||
(json['chaptersTotal'] as num?)?.toInt(),
|
||||
json['thumbnailUrl'] as String,
|
||||
const TrackingDataSourceConverter().fromJson(json['source'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MangaTrackingDataToJson(_MangaTrackingData instance) =>
|
||||
@@ -28,4 +29,5 @@ Map<String, dynamic> _$MangaTrackingDataToJson(_MangaTrackingData instance) =>
|
||||
'volumesOwned': instance.volumesOwned,
|
||||
'chaptersTotal': instance.chaptersTotal,
|
||||
'thumbnailUrl': instance.thumbnailUrl,
|
||||
'source': const TrackingDataSourceConverter().toJson(instance.source),
|
||||
};
|
||||
|
||||
22
lib/src/data/source.dart
Normal file
22
lib/src/data/source.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
enum TrackingDataSource {
|
||||
mal('mal'),
|
||||
anilist('anilist');
|
||||
|
||||
const TrackingDataSource(this.value);
|
||||
|
||||
final String value;
|
||||
}
|
||||
|
||||
class TrackingDataSourceConverter
|
||||
implements JsonConverter<TrackingDataSource, String> {
|
||||
const TrackingDataSourceConverter();
|
||||
|
||||
@override
|
||||
TrackingDataSource fromJson(String json) =>
|
||||
TrackingDataSource.values.where((val) => val.value == json).first;
|
||||
|
||||
@override
|
||||
String toJson(TrackingDataSource source) => source.value;
|
||||
}
|
||||
132
lib/src/service/anilist/anilist_client.dart
Normal file
132
lib/src/service/anilist/anilist_client.dart
Normal file
@@ -0,0 +1,132 @@
|
||||
import 'package:anitrack/src/service/anilist/model.dart';
|
||||
import 'package:graphql/client.dart';
|
||||
|
||||
class AniListClient {
|
||||
/// The base GraphQL client for AniList
|
||||
final _client = GraphQLClient(
|
||||
link: HttpLink("https://graphql.anilist.co"),
|
||||
cache: GraphQLCache(),
|
||||
);
|
||||
|
||||
Future<List<AnimeSearchResult>> searchAnime(String q) async {
|
||||
const query = r'''
|
||||
query ($search: String!) {
|
||||
Page {
|
||||
media(search: $search, type: ANIME) {
|
||||
id
|
||||
status
|
||||
coverImage {
|
||||
medium
|
||||
}
|
||||
episodes
|
||||
description
|
||||
nextAiringEpisode {
|
||||
airingAt
|
||||
}
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
final result = await _client.query(
|
||||
QueryOptions(
|
||||
document: gql(query),
|
||||
variables: {
|
||||
'search': q,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (result.hasException) {
|
||||
// TODO: Handle this more elegantly
|
||||
print(result.exception.toString());
|
||||
return [];
|
||||
}
|
||||
|
||||
return (result.data!["Page"]["media"] as List<Object?>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map(AnimeSearchResult.fromJson)
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<List<MangaSearchResult>> searchManga(String q) async {
|
||||
const query = r'''
|
||||
query ($search: String!) {
|
||||
Page {
|
||||
media(search: $search, type: MANGA) {
|
||||
id
|
||||
status
|
||||
coverImage {
|
||||
medium
|
||||
}
|
||||
chapters
|
||||
description
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
final result = await _client.query(
|
||||
QueryOptions(
|
||||
document: gql(query),
|
||||
variables: {
|
||||
'search': q,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (result.hasException) {
|
||||
// TODO: Handle this more elegantly
|
||||
print(result.exception.toString());
|
||||
return [];
|
||||
}
|
||||
|
||||
return (result.data!["Page"]["media"] as List<Object?>)
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map(MangaSearchResult.fromJson)
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<Anime> getAnimeById(String id) async {
|
||||
const query = r'''
|
||||
query ($id: Int) {
|
||||
Media (id: $id) {
|
||||
id
|
||||
status
|
||||
nextAiringEpisode {
|
||||
airingAt
|
||||
}
|
||||
title {
|
||||
romaji
|
||||
english
|
||||
native
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
final result = await _client.query(
|
||||
QueryOptions(
|
||||
document: gql(query),
|
||||
variables: {
|
||||
'id': id,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (result.hasException) {
|
||||
print(result.exception.toString());
|
||||
}
|
||||
|
||||
return Anime.fromJson(result.data!['Media'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
/*
|
||||
Future<dynamic> getMangaById(String id) {
|
||||
|
||||
}*/
|
||||
}
|
||||
13
lib/src/service/anilist/helpers.dart
Normal file
13
lib/src/service/anilist/helpers.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
const _weekdays = [
|
||||
'Mondays',
|
||||
'Tuesdays',
|
||||
'Wednesdays',
|
||||
'Thursdays',
|
||||
'Fridays',
|
||||
'Saturdays',
|
||||
'Sundays',
|
||||
];
|
||||
|
||||
String getAiringDay(int timestamp) {
|
||||
return _weekdays[DateTime.fromMillisecondsSinceEpoch(timestamp).weekday];
|
||||
}
|
||||
82
lib/src/service/anilist/model.dart
Normal file
82
lib/src/service/anilist/model.dart
Normal file
@@ -0,0 +1,82 @@
|
||||
import 'package:anitrack/src/service/anilist/helpers.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'model.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class AnimeSearchResult with _$AnimeSearchResult {
|
||||
const factory AnimeSearchResult({
|
||||
required String title,
|
||||
required String id,
|
||||
required int? episodes,
|
||||
required String imageUrl,
|
||||
required String? description,
|
||||
required bool isAiring,
|
||||
required String? broadcastDay,
|
||||
}) = _AnimeSearchResult;
|
||||
|
||||
factory AnimeSearchResult.fromJson(Map<String, Object?> json) {
|
||||
final airingDayOfTheWeek = json['nextAiringEpisode'] == null
|
||||
? null
|
||||
: getAiringDay(
|
||||
(json['nextAiringEpisode']! as Map<String, dynamic>)['airingAt']!
|
||||
as int,
|
||||
);
|
||||
return AnimeSearchResult(
|
||||
title: (json['title']! as Map<String, dynamic>)['romaji']! as String,
|
||||
id: (json['id']! as int).toString(),
|
||||
episodes: json['episodes'] as int?,
|
||||
imageUrl:
|
||||
(json['coverImage']! as Map<String, dynamic>)['medium']! as String,
|
||||
description: json['description'] as String?,
|
||||
isAiring: json['status'] == 'RELEASING',
|
||||
broadcastDay: airingDayOfTheWeek,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class MangaSearchResult with _$MangaSearchResult {
|
||||
const factory MangaSearchResult({
|
||||
required String title,
|
||||
required String id,
|
||||
required int? chapters,
|
||||
required String imageUrl,
|
||||
required String? description,
|
||||
}) = _MangaSearchResult;
|
||||
|
||||
factory MangaSearchResult.fromJson(Map<String, Object?> json) {
|
||||
return MangaSearchResult(
|
||||
title: (json['title']! as Map<String, dynamic>)['romaji']! as String,
|
||||
id: (json['id']! as int).toString(),
|
||||
chapters: json['chapters'] as int?,
|
||||
imageUrl:
|
||||
(json['coverImage']! as Map<String, dynamic>)['medium']! as String,
|
||||
description: json['description'] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class Anime with _$Anime {
|
||||
const factory Anime({
|
||||
required String title,
|
||||
required bool isAiring,
|
||||
required String? broadcastDay,
|
||||
}) = _Anime;
|
||||
|
||||
factory Anime.fromJson(Map<String, Object?> json) {
|
||||
final airingDayOfTheWeek = json['nextAiringEpisode'] == null
|
||||
? null
|
||||
: getAiringDay(
|
||||
(json['nextAiringEpisode']! as Map<String, dynamic>)['airingAt']!
|
||||
as int,
|
||||
);
|
||||
|
||||
return Anime(
|
||||
title: (json['title']! as Map<String, dynamic>)['romaji']! as String,
|
||||
isAiring: json['status'] == 'RELEASING',
|
||||
broadcastDay: airingDayOfTheWeek,
|
||||
);
|
||||
}
|
||||
}
|
||||
821
lib/src/service/anilist/model.freezed.dart
Normal file
821
lib/src/service/anilist/model.freezed.dart
Normal file
@@ -0,0 +1,821 @@
|
||||
// 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 'model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$AnimeSearchResult {
|
||||
|
||||
String get title; String get id; int? get episodes; String get imageUrl; String? get description; bool get isAiring; String? get broadcastDay;
|
||||
/// Create a copy of AnimeSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AnimeSearchResultCopyWith<AnimeSearchResult> get copyWith => _$AnimeSearchResultCopyWithImpl<AnimeSearchResult>(this as AnimeSearchResult, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AnimeSearchResult&&(identical(other.title, title) || other.title == title)&&(identical(other.id, id) || other.id == id)&&(identical(other.episodes, episodes) || other.episodes == episodes)&&(identical(other.imageUrl, imageUrl) || other.imageUrl == imageUrl)&&(identical(other.description, description) || other.description == description)&&(identical(other.isAiring, isAiring) || other.isAiring == isAiring)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,id,episodes,imageUrl,description,isAiring,broadcastDay);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AnimeSearchResult(title: $title, id: $id, episodes: $episodes, imageUrl: $imageUrl, description: $description, isAiring: $isAiring, broadcastDay: $broadcastDay)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $AnimeSearchResultCopyWith<$Res> {
|
||||
factory $AnimeSearchResultCopyWith(AnimeSearchResult value, $Res Function(AnimeSearchResult) _then) = _$AnimeSearchResultCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String title, String id, int? episodes, String imageUrl, String? description, bool isAiring, String? broadcastDay
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AnimeSearchResultCopyWithImpl<$Res>
|
||||
implements $AnimeSearchResultCopyWith<$Res> {
|
||||
_$AnimeSearchResultCopyWithImpl(this._self, this._then);
|
||||
|
||||
final AnimeSearchResult _self;
|
||||
final $Res Function(AnimeSearchResult) _then;
|
||||
|
||||
/// Create a copy of AnimeSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? title = null,Object? id = null,Object? episodes = freezed,Object? imageUrl = null,Object? description = freezed,Object? isAiring = null,Object? broadcastDay = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,episodes: freezed == episodes ? _self.episodes : episodes // ignore: cast_nullable_to_non_nullable
|
||||
as int?,imageUrl: null == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,isAiring: null == isAiring ? _self.isAiring : isAiring // ignore: cast_nullable_to_non_nullable
|
||||
as bool,broadcastDay: freezed == broadcastDay ? _self.broadcastDay : broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [AnimeSearchResult].
|
||||
extension AnimeSearchResultPatterns on AnimeSearchResult {
|
||||
/// 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( _AnimeSearchResult value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeSearchResult() 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( _AnimeSearchResult value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeSearchResult():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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( _AnimeSearchResult value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeSearchResult() 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 title, String id, int? episodes, String imageUrl, String? description, bool isAiring, String? broadcastDay)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeSearchResult() when $default != null:
|
||||
return $default(_that.title,_that.id,_that.episodes,_that.imageUrl,_that.description,_that.isAiring,_that.broadcastDay);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 title, String id, int? episodes, String imageUrl, String? description, bool isAiring, String? broadcastDay) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeSearchResult():
|
||||
return $default(_that.title,_that.id,_that.episodes,_that.imageUrl,_that.description,_that.isAiring,_that.broadcastDay);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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 title, String id, int? episodes, String imageUrl, String? description, bool isAiring, String? broadcastDay)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _AnimeSearchResult() when $default != null:
|
||||
return $default(_that.title,_that.id,_that.episodes,_that.imageUrl,_that.description,_that.isAiring,_that.broadcastDay);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _AnimeSearchResult implements AnimeSearchResult {
|
||||
const _AnimeSearchResult({required this.title, required this.id, required this.episodes, required this.imageUrl, required this.description, required this.isAiring, required this.broadcastDay});
|
||||
|
||||
|
||||
@override final String title;
|
||||
@override final String id;
|
||||
@override final int? episodes;
|
||||
@override final String imageUrl;
|
||||
@override final String? description;
|
||||
@override final bool isAiring;
|
||||
@override final String? broadcastDay;
|
||||
|
||||
/// Create a copy of AnimeSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AnimeSearchResultCopyWith<_AnimeSearchResult> get copyWith => __$AnimeSearchResultCopyWithImpl<_AnimeSearchResult>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AnimeSearchResult&&(identical(other.title, title) || other.title == title)&&(identical(other.id, id) || other.id == id)&&(identical(other.episodes, episodes) || other.episodes == episodes)&&(identical(other.imageUrl, imageUrl) || other.imageUrl == imageUrl)&&(identical(other.description, description) || other.description == description)&&(identical(other.isAiring, isAiring) || other.isAiring == isAiring)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,id,episodes,imageUrl,description,isAiring,broadcastDay);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AnimeSearchResult(title: $title, id: $id, episodes: $episodes, imageUrl: $imageUrl, description: $description, isAiring: $isAiring, broadcastDay: $broadcastDay)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AnimeSearchResultCopyWith<$Res> implements $AnimeSearchResultCopyWith<$Res> {
|
||||
factory _$AnimeSearchResultCopyWith(_AnimeSearchResult value, $Res Function(_AnimeSearchResult) _then) = __$AnimeSearchResultCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String title, String id, int? episodes, String imageUrl, String? description, bool isAiring, String? broadcastDay
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AnimeSearchResultCopyWithImpl<$Res>
|
||||
implements _$AnimeSearchResultCopyWith<$Res> {
|
||||
__$AnimeSearchResultCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _AnimeSearchResult _self;
|
||||
final $Res Function(_AnimeSearchResult) _then;
|
||||
|
||||
/// Create a copy of AnimeSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? title = null,Object? id = null,Object? episodes = freezed,Object? imageUrl = null,Object? description = freezed,Object? isAiring = null,Object? broadcastDay = freezed,}) {
|
||||
return _then(_AnimeSearchResult(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,episodes: freezed == episodes ? _self.episodes : episodes // ignore: cast_nullable_to_non_nullable
|
||||
as int?,imageUrl: null == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,isAiring: null == isAiring ? _self.isAiring : isAiring // ignore: cast_nullable_to_non_nullable
|
||||
as bool,broadcastDay: freezed == broadcastDay ? _self.broadcastDay : broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MangaSearchResult {
|
||||
|
||||
String get title; String get id; int? get chapters; String get imageUrl; String? get description;
|
||||
/// Create a copy of MangaSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$MangaSearchResultCopyWith<MangaSearchResult> get copyWith => _$MangaSearchResultCopyWithImpl<MangaSearchResult>(this as MangaSearchResult, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is MangaSearchResult&&(identical(other.title, title) || other.title == title)&&(identical(other.id, id) || other.id == id)&&(identical(other.chapters, chapters) || other.chapters == chapters)&&(identical(other.imageUrl, imageUrl) || other.imageUrl == imageUrl)&&(identical(other.description, description) || other.description == description));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,id,chapters,imageUrl,description);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MangaSearchResult(title: $title, id: $id, chapters: $chapters, imageUrl: $imageUrl, description: $description)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $MangaSearchResultCopyWith<$Res> {
|
||||
factory $MangaSearchResultCopyWith(MangaSearchResult value, $Res Function(MangaSearchResult) _then) = _$MangaSearchResultCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String title, String id, int? chapters, String imageUrl, String? description
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$MangaSearchResultCopyWithImpl<$Res>
|
||||
implements $MangaSearchResultCopyWith<$Res> {
|
||||
_$MangaSearchResultCopyWithImpl(this._self, this._then);
|
||||
|
||||
final MangaSearchResult _self;
|
||||
final $Res Function(MangaSearchResult) _then;
|
||||
|
||||
/// Create a copy of MangaSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? title = null,Object? id = null,Object? chapters = freezed,Object? imageUrl = null,Object? description = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,chapters: freezed == chapters ? _self.chapters : chapters // ignore: cast_nullable_to_non_nullable
|
||||
as int?,imageUrl: null == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [MangaSearchResult].
|
||||
extension MangaSearchResultPatterns on MangaSearchResult {
|
||||
/// 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( _MangaSearchResult value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaSearchResult() 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( _MangaSearchResult value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaSearchResult():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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( _MangaSearchResult value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaSearchResult() 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 title, String id, int? chapters, String imageUrl, String? description)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaSearchResult() when $default != null:
|
||||
return $default(_that.title,_that.id,_that.chapters,_that.imageUrl,_that.description);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 title, String id, int? chapters, String imageUrl, String? description) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaSearchResult():
|
||||
return $default(_that.title,_that.id,_that.chapters,_that.imageUrl,_that.description);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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 title, String id, int? chapters, String imageUrl, String? description)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MangaSearchResult() when $default != null:
|
||||
return $default(_that.title,_that.id,_that.chapters,_that.imageUrl,_that.description);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _MangaSearchResult implements MangaSearchResult {
|
||||
const _MangaSearchResult({required this.title, required this.id, required this.chapters, required this.imageUrl, required this.description});
|
||||
|
||||
|
||||
@override final String title;
|
||||
@override final String id;
|
||||
@override final int? chapters;
|
||||
@override final String imageUrl;
|
||||
@override final String? description;
|
||||
|
||||
/// Create a copy of MangaSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$MangaSearchResultCopyWith<_MangaSearchResult> get copyWith => __$MangaSearchResultCopyWithImpl<_MangaSearchResult>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MangaSearchResult&&(identical(other.title, title) || other.title == title)&&(identical(other.id, id) || other.id == id)&&(identical(other.chapters, chapters) || other.chapters == chapters)&&(identical(other.imageUrl, imageUrl) || other.imageUrl == imageUrl)&&(identical(other.description, description) || other.description == description));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,id,chapters,imageUrl,description);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MangaSearchResult(title: $title, id: $id, chapters: $chapters, imageUrl: $imageUrl, description: $description)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$MangaSearchResultCopyWith<$Res> implements $MangaSearchResultCopyWith<$Res> {
|
||||
factory _$MangaSearchResultCopyWith(_MangaSearchResult value, $Res Function(_MangaSearchResult) _then) = __$MangaSearchResultCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String title, String id, int? chapters, String imageUrl, String? description
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$MangaSearchResultCopyWithImpl<$Res>
|
||||
implements _$MangaSearchResultCopyWith<$Res> {
|
||||
__$MangaSearchResultCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _MangaSearchResult _self;
|
||||
final $Res Function(_MangaSearchResult) _then;
|
||||
|
||||
/// Create a copy of MangaSearchResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? title = null,Object? id = null,Object? chapters = freezed,Object? imageUrl = null,Object? description = freezed,}) {
|
||||
return _then(_MangaSearchResult(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,chapters: freezed == chapters ? _self.chapters : chapters // ignore: cast_nullable_to_non_nullable
|
||||
as int?,imageUrl: null == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$Anime {
|
||||
|
||||
String get title; bool get isAiring; String? get broadcastDay;
|
||||
/// Create a copy of Anime
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AnimeCopyWith<Anime> get copyWith => _$AnimeCopyWithImpl<Anime>(this as Anime, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is Anime&&(identical(other.title, title) || other.title == title)&&(identical(other.isAiring, isAiring) || other.isAiring == isAiring)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,isAiring,broadcastDay);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Anime(title: $title, isAiring: $isAiring, broadcastDay: $broadcastDay)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $AnimeCopyWith<$Res> {
|
||||
factory $AnimeCopyWith(Anime value, $Res Function(Anime) _then) = _$AnimeCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String title, bool isAiring, String? broadcastDay
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AnimeCopyWithImpl<$Res>
|
||||
implements $AnimeCopyWith<$Res> {
|
||||
_$AnimeCopyWithImpl(this._self, this._then);
|
||||
|
||||
final Anime _self;
|
||||
final $Res Function(Anime) _then;
|
||||
|
||||
/// Create a copy of Anime
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? title = null,Object? isAiring = null,Object? broadcastDay = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,isAiring: null == isAiring ? _self.isAiring : isAiring // ignore: cast_nullable_to_non_nullable
|
||||
as bool,broadcastDay: freezed == broadcastDay ? _self.broadcastDay : broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [Anime].
|
||||
extension AnimePatterns on Anime {
|
||||
/// 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( _Anime value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime() 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( _Anime value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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( _Anime value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime() 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 title, bool isAiring, String? broadcastDay)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime() when $default != null:
|
||||
return $default(_that.title,_that.isAiring,_that.broadcastDay);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 title, bool isAiring, String? broadcastDay) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime():
|
||||
return $default(_that.title,_that.isAiring,_that.broadcastDay);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// 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 title, bool isAiring, String? broadcastDay)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _Anime() when $default != null:
|
||||
return $default(_that.title,_that.isAiring,_that.broadcastDay);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
|
||||
class _Anime implements Anime {
|
||||
const _Anime({required this.title, required this.isAiring, required this.broadcastDay});
|
||||
|
||||
|
||||
@override final String title;
|
||||
@override final bool isAiring;
|
||||
@override final String? broadcastDay;
|
||||
|
||||
/// Create a copy of Anime
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AnimeCopyWith<_Anime> get copyWith => __$AnimeCopyWithImpl<_Anime>(this, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Anime&&(identical(other.title, title) || other.title == title)&&(identical(other.isAiring, isAiring) || other.isAiring == isAiring)&&(identical(other.broadcastDay, broadcastDay) || other.broadcastDay == broadcastDay));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,title,isAiring,broadcastDay);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Anime(title: $title, isAiring: $isAiring, broadcastDay: $broadcastDay)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AnimeCopyWith<$Res> implements $AnimeCopyWith<$Res> {
|
||||
factory _$AnimeCopyWith(_Anime value, $Res Function(_Anime) _then) = __$AnimeCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String title, bool isAiring, String? broadcastDay
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AnimeCopyWithImpl<$Res>
|
||||
implements _$AnimeCopyWith<$Res> {
|
||||
__$AnimeCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Anime _self;
|
||||
final $Res Function(_Anime) _then;
|
||||
|
||||
/// Create a copy of Anime
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? title = null,Object? isAiring = null,Object? broadcastDay = freezed,}) {
|
||||
return _then(_Anime(
|
||||
title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
as String,isAiring: null == isAiring ? _self.isAiring : isAiring // ignore: cast_nullable_to_non_nullable
|
||||
as bool,broadcastDay: freezed == broadcastDay ? _self.broadcastDay : broadcastDay // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -6,6 +6,7 @@ import 'package:anitrack/src/data/manga.dart';
|
||||
import 'package:anitrack/src/service/migrations/0000_airing.dart';
|
||||
import 'package:anitrack/src/service/migrations/0000_score.dart';
|
||||
import 'package:anitrack/src/service/migrations/0001_anime_watcher.dart';
|
||||
import 'package:anitrack/src/service/migrations/0002_anilist.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
|
||||
const animeTable = 'Anime';
|
||||
@@ -38,7 +39,8 @@ Future<void> _createDatabase(Database db, int version) async {
|
||||
otherTitles TEXT NOT NULL,
|
||||
score INTEGER,
|
||||
airing INTEGER NOT NULL,
|
||||
broadcastDay TEXT
|
||||
broadcastDay TEXT,
|
||||
source TEXT NOT NULL
|
||||
)''',
|
||||
);
|
||||
await db.execute(
|
||||
@@ -52,7 +54,8 @@ Future<void> _createDatabase(Database db, int version) async {
|
||||
thumbnailUrl TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
otherTitles TEXT NOT NULL,
|
||||
score INTEGER
|
||||
score INTEGER,
|
||||
source TEXT NOT NULL
|
||||
)''',
|
||||
);
|
||||
await db.execute(
|
||||
@@ -89,7 +92,7 @@ class DatabaseService {
|
||||
|
||||
_db = await openDatabase(
|
||||
'anitrack.db',
|
||||
version: 4,
|
||||
version: 5,
|
||||
onConfigure: (db) async {
|
||||
// In order to do schema changes during database upgrades, we disable foreign
|
||||
// keys in the onConfigure phase, but re-enable them here.
|
||||
@@ -111,6 +114,9 @@ class DatabaseService {
|
||||
if (oldVersion < 4) {
|
||||
await migrateFromV3ToV4(db);
|
||||
}
|
||||
if (oldVersion < 5) {
|
||||
await migrateFromV4ToV5(db);
|
||||
}
|
||||
},
|
||||
);
|
||||
print(_db.path);
|
||||
|
||||
15
lib/src/service/migrations/0002_anilist.dart
Normal file
15
lib/src/service/migrations/0002_anilist.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:anitrack/src/service/database.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
Future<void> migrateFromV4ToV5(Database db) async {
|
||||
await db.execute(
|
||||
'''
|
||||
ALTER TABLE $animeTable ADD COLUMN source TEXT NOT NULL DEFAULT 'mal';
|
||||
''',
|
||||
);
|
||||
await db.execute(
|
||||
'''
|
||||
ALTER TABLE $mangaTable ADD COLUMN source TEXT NOT NULL DEFAULT 'mal';
|
||||
''',
|
||||
);
|
||||
}
|
||||
@@ -317,9 +317,9 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
||||
);
|
||||
|
||||
// Update the cache
|
||||
final cacheIndex = _mangas.indexWhere((m) => m.id == event.id);
|
||||
final cacheIndex = _animes.indexWhere((m) => m.id == event.id);
|
||||
assert(cacheIndex != -1, 'The anime must exist');
|
||||
_mangas.removeAt(cacheIndex);
|
||||
_animes.removeAt(cacheIndex);
|
||||
|
||||
// Update the database
|
||||
await GetIt.I.get<DatabaseService>().deleteAnime(event.id);
|
||||
@@ -338,9 +338,9 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
||||
);
|
||||
|
||||
// Update the cache
|
||||
final cacheIndex = _animes.indexWhere((a) => a.id == event.id);
|
||||
final cacheIndex = _mangas.indexWhere((a) => a.id == event.id);
|
||||
assert(cacheIndex != -1, 'The manga must exist');
|
||||
_animes.removeAt(cacheIndex);
|
||||
_mangas.removeAt(cacheIndex);
|
||||
|
||||
// Update the database
|
||||
await GetIt.I.get<DatabaseService>().deleteManga(event.id);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import 'package:anitrack/src/data/anime.dart';
|
||||
import 'package:anitrack/src/data/manga.dart';
|
||||
import 'package:anitrack/src/data/search_result.dart';
|
||||
import 'package:anitrack/src/data/source.dart';
|
||||
import 'package:anitrack/src/data/type.dart';
|
||||
import 'package:anitrack/src/service/anilist/anilist_client.dart';
|
||||
import 'package:anitrack/src/service/anilist/model.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart' as list;
|
||||
import 'package:anitrack/src/ui/bloc/navigation_bloc.dart';
|
||||
import 'package:anitrack/src/ui/constants.dart';
|
||||
@@ -22,6 +25,9 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
||||
on<ResultTappedEvent>(_onResultTapped);
|
||||
}
|
||||
|
||||
// The client to use for AniList GraphQL queries.
|
||||
final _anilistClient = AniListClient();
|
||||
|
||||
Future<void> _onRequested(
|
||||
AnimeSearchRequestedEvent event,
|
||||
Emitter<AnimeSearchState> emit,
|
||||
@@ -67,23 +73,21 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
||||
|
||||
if (state.trackingType == TrackingMediumType.anime) {
|
||||
// Anime
|
||||
final result = await Jikan().searchAnime(
|
||||
query: state.searchQuery,
|
||||
);
|
||||
final result = await _anilistClient.searchAnime(state.searchQuery);
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
working: false,
|
||||
searchResults: result
|
||||
.map(
|
||||
(Anime anime) => SearchResult(
|
||||
(anime) => SearchResult(
|
||||
anime.title,
|
||||
anime.malId.toString(),
|
||||
anime.id,
|
||||
anime.episodes,
|
||||
anime.imageUrl,
|
||||
anime.synopsis ?? '',
|
||||
anime.airing,
|
||||
anime.broadcast?.split(' ').first,
|
||||
anime.description ?? '',
|
||||
anime.isAiring,
|
||||
anime.broadcastDay,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
@@ -91,21 +95,19 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
||||
);
|
||||
} else {
|
||||
// Manga
|
||||
final result = await Jikan().searchManga(
|
||||
query: state.searchQuery,
|
||||
);
|
||||
final result = await _anilistClient.searchManga(state.searchQuery);
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
working: false,
|
||||
searchResults: result
|
||||
.map(
|
||||
(Manga manga) => SearchResult(
|
||||
(manga) => SearchResult(
|
||||
manga.title,
|
||||
manga.malId.toString(),
|
||||
manga.id,
|
||||
manga.chapters,
|
||||
manga.imageUrl,
|
||||
manga.synopsis ?? '',
|
||||
manga.description ?? '',
|
||||
// TODO(Unknown): Implement for Manga
|
||||
false,
|
||||
null,
|
||||
@@ -133,6 +135,7 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
||||
event.result.thumbnailUrl,
|
||||
event.result.isAiring,
|
||||
event.result.broadcastDay,
|
||||
TrackingDataSource.anilist,
|
||||
),
|
||||
)
|
||||
: list.MangaAddedEvent(
|
||||
@@ -144,6 +147,7 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
||||
0,
|
||||
event.result.total,
|
||||
event.result.thumbnailUrl,
|
||||
TrackingDataSource.anilist,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:anitrack/src/data/source.dart';
|
||||
import 'package:anitrack/src/service/anilist/anilist_client.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@@ -43,9 +45,18 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
||||
String? broadcastDay;
|
||||
bool airing;
|
||||
try {
|
||||
final apiData = await Jikan().getAnime(int.parse(anime.id));
|
||||
airing = apiData.airing;
|
||||
broadcastDay = apiData.broadcast?.split(' ').first;
|
||||
switch (anime.source) {
|
||||
case TrackingDataSource.mal:
|
||||
final apiData = await Jikan().getAnime(int.parse(anime.id));
|
||||
airing = apiData.airing;
|
||||
broadcastDay = apiData.broadcast?.split(' ').first;
|
||||
case TrackingDataSource.anilist:
|
||||
final apiData = await GetIt.I.get<AniListClient>().getAnimeById(
|
||||
anime.id,
|
||||
);
|
||||
airing = apiData.isAiring;
|
||||
broadcastDay = apiData.broadcastDay;
|
||||
}
|
||||
} catch (ex) {
|
||||
print('API request for anime ${anime.id} failed: $ex');
|
||||
airing = false;
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:io';
|
||||
import 'package:anitrack/i18n/strings.g.dart';
|
||||
import 'package:anitrack/src/data/anime.dart';
|
||||
import 'package:anitrack/src/data/manga.dart';
|
||||
import 'package:anitrack/src/data/source.dart';
|
||||
import 'package:anitrack/src/data/type.dart';
|
||||
import 'package:anitrack/src/service/database.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||
@@ -131,6 +132,7 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
|
||||
// NOTE: When the calendar gets refreshed, this should also get cleared
|
||||
true,
|
||||
null,
|
||||
TrackingDataSource.mal,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -207,6 +209,7 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
|
||||
// 0 means that MAL does not know
|
||||
totalChapters == 0 ? null : totalChapters,
|
||||
data.imageUrl,
|
||||
TrackingDataSource.mal,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -122,8 +122,7 @@ class CalendarPageState extends State<CalendarPage> {
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Map<Weekday, List<AnimeTrackingData>> _constructAiringMap() {
|
||||
final airingAnimeMap = <Weekday, List<AnimeTrackingData>>{};
|
||||
for (final anime in GetIt.I.get<AnimeListBloc>().unfilteredAnime) {
|
||||
if (!anime.airing) continue;
|
||||
@@ -158,166 +157,176 @@ class CalendarPageState extends State<CalendarPage> {
|
||||
|
||||
airingAnimeMap.addOrSet(day, anime);
|
||||
}
|
||||
return airingAnimeMap;
|
||||
}
|
||||
|
||||
return BlocListener<CalendarBloc, CalendarState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.refreshing != current.refreshing,
|
||||
listener: (context, state) {
|
||||
// Force an update
|
||||
if (!state.refreshing) {
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
child: WillPopScope(
|
||||
onWillPop: () async => !context.read<CalendarBloc>().state.refreshing,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(t.calendar.calendar),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.read<CalendarBloc>().add(
|
||||
RefreshPerformedEvent(),
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.refresh),
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<AnimeListBloc, AnimeListState>(
|
||||
builder: (context, animeListState) {
|
||||
final airingAnimeMap = _constructAiringMap();
|
||||
return BlocListener<CalendarBloc, CalendarState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.refreshing != current.refreshing,
|
||||
listener: (context, state) {
|
||||
// Force an update
|
||||
if (!state.refreshing) {
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
child: WillPopScope(
|
||||
onWillPop: () async =>
|
||||
!context.read<CalendarBloc>().state.refreshing,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(t.calendar.calendar),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.read<CalendarBloc>().add(
|
||||
RefreshPerformedEvent(),
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.refresh),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
drawer: getDrawer(context),
|
||||
body: Padding(
|
||||
padding: const EdgeInsetsGeometry.symmetric(
|
||||
horizontal: 12,
|
||||
),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
// Render all available weekdays
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.unknown,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.monday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.tuesday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.wednesday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.thursday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.friday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.saturday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.sunday,
|
||||
airingAnimeMap,
|
||||
drawer: getDrawer(context),
|
||||
body: Padding(
|
||||
padding: const EdgeInsetsGeometry.symmetric(
|
||||
horizontal: 12,
|
||||
),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
// Render all available weekdays
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.unknown,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.monday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.tuesday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.wednesday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.thursday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.friday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.saturday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
..._renderWeekdayList(
|
||||
context,
|
||||
Weekday.sunday,
|
||||
airingAnimeMap,
|
||||
),
|
||||
|
||||
// Provide a nice bottom padding, while keeping the elastic effect attached
|
||||
// to the bottom-most edge.
|
||||
const SliverToBoxAdapter(
|
||||
// Provide a nice bottom padding, while keeping the elastic effect attached
|
||||
// to the bottom-most edge.
|
||||
const SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: BlocBuilder<CalendarBloc, CalendarState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.refreshing != current.refreshing,
|
||||
builder: (context, state) {
|
||||
if (!state.refreshing) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return const ModalBarrier(
|
||||
dismissible: false,
|
||||
color: Colors.black54,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: BlocBuilder<CalendarBloc, CalendarState>(
|
||||
builder: (context, state) {
|
||||
if (!state.refreshing) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
height: 16,
|
||||
width: 150,
|
||||
height: 150,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(25),
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
Text(
|
||||
t.settings.importIndicator(
|
||||
current: state.refreshingCount,
|
||||
total: state.refreshingTotal,
|
||||
),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: BlocBuilder<CalendarBloc, CalendarState>(
|
||||
buildWhen: (previous, current) =>
|
||||
previous.refreshing != current.refreshing,
|
||||
builder: (context, state) {
|
||||
if (!state.refreshing) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return const ModalBarrier(
|
||||
dismissible: false,
|
||||
color: Colors.black54,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: BlocBuilder<CalendarBloc, CalendarState>(
|
||||
builder: (context, state) {
|
||||
if (!state.refreshing) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 150,
|
||||
height: 150,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(25),
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
Text(
|
||||
t.settings.importIndicator(
|
||||
current: state.refreshingCount,
|
||||
total: state.refreshingTotal,
|
||||
),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user