chore(all): Format
This commit is contained in:
parent
67c1903bd1
commit
9dcc99ca36
File diff suppressed because it is too large
Load Diff
@ -81,10 +81,14 @@ class MyApp extends StatelessWidget {
|
|||||||
onGenerateRoute: (settings) {
|
onGenerateRoute: (settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
case '/':
|
case '/':
|
||||||
case animeListRoute: return AnimeListPage.route;
|
case animeListRoute:
|
||||||
case animeSearchRoute: return AnimeSearchPage.route;
|
return AnimeListPage.route;
|
||||||
case detailsRoute: return DetailsPage.route;
|
case animeSearchRoute:
|
||||||
case aboutRoute: return AboutPage.route;
|
return AnimeSearchPage.route;
|
||||||
|
case detailsRoute:
|
||||||
|
return DetailsPage.route;
|
||||||
|
case aboutRoute:
|
||||||
|
return AboutPage.route;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -10,18 +10,24 @@ class AnimeTrackingData with _$AnimeTrackingData, TrackingMedium {
|
|||||||
factory AnimeTrackingData(
|
factory AnimeTrackingData(
|
||||||
/// The ID of the anime
|
/// The ID of the anime
|
||||||
String id,
|
String id,
|
||||||
|
|
||||||
/// The state of the anime
|
/// The state of the anime
|
||||||
@MediumTrackingStateConverter() MediumTrackingState state,
|
@MediumTrackingStateConverter() MediumTrackingState state,
|
||||||
|
|
||||||
/// The title of the anime
|
/// The title of the anime
|
||||||
String title,
|
String title,
|
||||||
|
|
||||||
/// Episodes in total.
|
/// Episodes in total.
|
||||||
int episodesWatched,
|
int episodesWatched,
|
||||||
|
|
||||||
/// Episodes watched.
|
/// Episodes watched.
|
||||||
int? episodesTotal,
|
int? episodesTotal,
|
||||||
|
|
||||||
/// URL to the thumbnail/cover art for the anime.
|
/// URL to the thumbnail/cover art for the anime.
|
||||||
String thumbnailUrl,
|
String thumbnailUrl,
|
||||||
) = _AnimeTrackingData;
|
) = _AnimeTrackingData;
|
||||||
|
|
||||||
/// JSON
|
/// JSON
|
||||||
factory AnimeTrackingData.fromJson(Map<String, dynamic> json) => _$AnimeTrackingDataFromJson(json);
|
factory AnimeTrackingData.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AnimeTrackingDataFromJson(json);
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,27 @@ class MangaTrackingData with _$MangaTrackingData, TrackingMedium {
|
|||||||
factory MangaTrackingData(
|
factory MangaTrackingData(
|
||||||
/// The ID of the manga
|
/// The ID of the manga
|
||||||
String id,
|
String id,
|
||||||
|
|
||||||
/// The state of the manga
|
/// The state of the manga
|
||||||
@MediumTrackingStateConverter() MediumTrackingState state,
|
@MediumTrackingStateConverter() MediumTrackingState state,
|
||||||
|
|
||||||
/// The title of the manga
|
/// The title of the manga
|
||||||
String title,
|
String title,
|
||||||
|
|
||||||
/// Chapters read.
|
/// Chapters read.
|
||||||
int chaptersRead,
|
int chaptersRead,
|
||||||
|
|
||||||
/// Chapters read.
|
/// Chapters read.
|
||||||
int volumesOwned,
|
int volumesOwned,
|
||||||
|
|
||||||
/// Episodes watched.
|
/// Episodes watched.
|
||||||
int? chaptersTotal,
|
int? chaptersTotal,
|
||||||
|
|
||||||
/// URL to the thumbnail/cover art for the manga.
|
/// URL to the thumbnail/cover art for the manga.
|
||||||
String thumbnailUrl,
|
String thumbnailUrl,
|
||||||
) = _MangaTrackingData;
|
) = _MangaTrackingData;
|
||||||
|
|
||||||
/// JSON
|
/// JSON
|
||||||
factory MangaTrackingData.fromJson(Map<String, dynamic> json) => _$MangaTrackingDataFromJson(json);
|
factory MangaTrackingData.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MangaTrackingDataFromJson(json);
|
||||||
}
|
}
|
||||||
|
@ -32,47 +32,70 @@ abstract class TrackingMedium {
|
|||||||
|
|
||||||
extension MediumStateExtension on MediumTrackingState {
|
extension MediumStateExtension on MediumTrackingState {
|
||||||
int toInteger() {
|
int toInteger() {
|
||||||
assert(this != MediumTrackingState.all, 'MediumTrackingState.all must not be serialized');
|
assert(
|
||||||
|
this != MediumTrackingState.all,
|
||||||
|
'MediumTrackingState.all must not be serialized',
|
||||||
|
);
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case MediumTrackingState.ongoing: return 0;
|
case MediumTrackingState.ongoing:
|
||||||
case MediumTrackingState.completed: return 1;
|
return 0;
|
||||||
case MediumTrackingState.planned: return 2;
|
case MediumTrackingState.completed:
|
||||||
case MediumTrackingState.dropped: return 3;
|
return 1;
|
||||||
case MediumTrackingState.all: return -1;
|
case MediumTrackingState.planned:
|
||||||
|
return 2;
|
||||||
|
case MediumTrackingState.dropped:
|
||||||
|
return 3;
|
||||||
|
case MediumTrackingState.all:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String toNameString(TrackingMediumType type) {
|
String toNameString(TrackingMediumType type) {
|
||||||
assert(this != MediumTrackingState.all, 'MediumTrackingState.all must not be stringified');
|
assert(
|
||||||
|
this != MediumTrackingState.all,
|
||||||
|
'MediumTrackingState.all must not be stringified',
|
||||||
|
);
|
||||||
|
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case MediumTrackingState.ongoing:
|
case MediumTrackingState.ongoing:
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TrackingMediumType.anime: return 'Watching';
|
case TrackingMediumType.anime:
|
||||||
case TrackingMediumType.manga: return 'Reading';
|
return 'Watching';
|
||||||
|
case TrackingMediumType.manga:
|
||||||
|
return 'Reading';
|
||||||
}
|
}
|
||||||
case MediumTrackingState.completed: return 'Completed';
|
case MediumTrackingState.completed:
|
||||||
|
return 'Completed';
|
||||||
case MediumTrackingState.planned:
|
case MediumTrackingState.planned:
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TrackingMediumType.anime: return 'Plan to watch';
|
case TrackingMediumType.anime:
|
||||||
case TrackingMediumType.manga: return 'Plan to read';
|
return 'Plan to watch';
|
||||||
|
case TrackingMediumType.manga:
|
||||||
|
return 'Plan to read';
|
||||||
}
|
}
|
||||||
case MediumTrackingState.dropped: return 'Dropped';
|
case MediumTrackingState.dropped:
|
||||||
case MediumTrackingState.all: return 'All';
|
return 'Dropped';
|
||||||
|
case MediumTrackingState.all:
|
||||||
|
return 'All';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MediumTrackingStateConverter implements JsonConverter<MediumTrackingState, int> {
|
class MediumTrackingStateConverter
|
||||||
|
implements JsonConverter<MediumTrackingState, int> {
|
||||||
const MediumTrackingStateConverter();
|
const MediumTrackingStateConverter();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MediumTrackingState fromJson(int json) {
|
MediumTrackingState fromJson(int json) {
|
||||||
switch (json) {
|
switch (json) {
|
||||||
case 0: return MediumTrackingState.ongoing;
|
case 0:
|
||||||
case 1: return MediumTrackingState.completed;
|
return MediumTrackingState.ongoing;
|
||||||
case 2: return MediumTrackingState.planned;
|
case 1:
|
||||||
case 3: return MediumTrackingState.dropped;
|
return MediumTrackingState.completed;
|
||||||
|
case 2:
|
||||||
|
return MediumTrackingState.planned;
|
||||||
|
case 3:
|
||||||
|
return MediumTrackingState.dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MediumTrackingState.planned;
|
return MediumTrackingState.planned;
|
||||||
|
@ -30,30 +30,35 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Internal anime state
|
/// Internal anime state
|
||||||
final List<AnimeTrackingData> _animes = List<AnimeTrackingData>.empty(growable: true);
|
final List<AnimeTrackingData> _animes =
|
||||||
final List<MangaTrackingData> _mangas = List<MangaTrackingData>.empty(growable: true);
|
List<AnimeTrackingData>.empty(growable: true);
|
||||||
|
final List<MangaTrackingData> _mangas =
|
||||||
|
List<MangaTrackingData>.empty(growable: true);
|
||||||
|
|
||||||
List<AnimeTrackingData> _getFilteredAnime({MediumTrackingState? trackingState}) {
|
List<AnimeTrackingData> _getFilteredAnime({
|
||||||
|
MediumTrackingState? trackingState,
|
||||||
|
}) {
|
||||||
final filterState = trackingState ?? state.animeFilterState;
|
final filterState = trackingState ?? state.animeFilterState;
|
||||||
|
|
||||||
if (filterState == MediumTrackingState.all) return _animes;
|
if (filterState == MediumTrackingState.all) return _animes;
|
||||||
|
|
||||||
return _animes
|
return _animes.where((anime) => anime.state == filterState).toList();
|
||||||
.where((anime) => anime.state == filterState)
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MangaTrackingData> _getFilteredManga({MediumTrackingState? trackingState}) {
|
List<MangaTrackingData> _getFilteredManga({
|
||||||
|
MediumTrackingState? trackingState,
|
||||||
|
}) {
|
||||||
final filterState = trackingState ?? state.mangaFilterState;
|
final filterState = trackingState ?? state.mangaFilterState;
|
||||||
|
|
||||||
if (state.mangaFilterState == MediumTrackingState.all) return _mangas;
|
if (state.mangaFilterState == MediumTrackingState.all) return _mangas;
|
||||||
|
|
||||||
return _mangas
|
return _mangas.where((manga) => manga.state == filterState).toList();
|
||||||
.where((manga) => manga.state == filterState)
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimeAdded(AnimeAddedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onAnimeAdded(
|
||||||
|
AnimeAddedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
// Add the anime to the database
|
// Add the anime to the database
|
||||||
await GetIt.I.get<DatabaseService>().addAnime(event.data);
|
await GetIt.I.get<DatabaseService>().addAnime(event.data);
|
||||||
|
|
||||||
@ -67,7 +72,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangaAdded(MangaAddedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onMangaAdded(
|
||||||
|
MangaAddedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
// Add the manga to the database
|
// Add the manga to the database
|
||||||
await GetIt.I.get<DatabaseService>().addManga(event.data);
|
await GetIt.I.get<DatabaseService>().addManga(event.data);
|
||||||
|
|
||||||
@ -81,12 +89,16 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimeIncremented(AnimeEpisodeIncrementedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onAnimeIncremented(
|
||||||
|
AnimeEpisodeIncrementedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
final index = state.animes.indexWhere((item) => item.id == event.id);
|
final index = state.animes.indexWhere((item) => item.id == event.id);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
|
|
||||||
final anime = state.animes[index];
|
final anime = state.animes[index];
|
||||||
if (anime.episodesTotal != null && anime.episodesWatched + 1 > anime.episodesTotal!) return;
|
if (anime.episodesTotal != null &&
|
||||||
|
anime.episodesWatched + 1 > anime.episodesTotal!) return;
|
||||||
|
|
||||||
final newList = List<AnimeTrackingData>.from(state.animes);
|
final newList = List<AnimeTrackingData>.from(state.animes);
|
||||||
final newAnime = anime.copyWith(
|
final newAnime = anime.copyWith(
|
||||||
@ -103,7 +115,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().updateAnime(newAnime);
|
await GetIt.I.get<DatabaseService>().updateAnime(newAnime);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimeDecremented(AnimeEpisodeDecrementedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onAnimeDecremented(
|
||||||
|
AnimeEpisodeDecrementedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
final index = state.animes.indexWhere((item) => item.id == event.id);
|
final index = state.animes.indexWhere((item) => item.id == event.id);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
|
|
||||||
@ -125,7 +140,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().updateAnime(newAnime);
|
await GetIt.I.get<DatabaseService>().updateAnime(newAnime);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimesLoaded(AnimesLoadedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onAnimesLoaded(
|
||||||
|
AnimesLoadedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
_animes.addAll(
|
_animes.addAll(
|
||||||
await GetIt.I.get<DatabaseService>().loadAnimes(),
|
await GetIt.I.get<DatabaseService>().loadAnimes(),
|
||||||
);
|
);
|
||||||
@ -141,7 +159,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimesFiltered(AnimeFilterChangedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onAnimesFiltered(
|
||||||
|
AnimeFilterChangedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
animeFilterState: event.filterState,
|
animeFilterState: event.filterState,
|
||||||
@ -150,7 +171,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangasFiltered(MangaFilterChangedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onMangasFiltered(
|
||||||
|
MangaFilterChangedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
mangaFilterState: event.filterState,
|
mangaFilterState: event.filterState,
|
||||||
@ -159,7 +183,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onTrackingTypeChanged(AnimeTrackingTypeChanged event, Emitter<AnimeListState> emit) async {
|
Future<void> _onTrackingTypeChanged(
|
||||||
|
AnimeTrackingTypeChanged event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
trackingType: event.type,
|
trackingType: event.type,
|
||||||
@ -168,12 +195,16 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangaIncremented(MangaChapterIncrementedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onMangaIncremented(
|
||||||
|
MangaChapterIncrementedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
final index = state.mangas.indexWhere((item) => item.id == event.id);
|
final index = state.mangas.indexWhere((item) => item.id == event.id);
|
||||||
assert(index != -1, 'The manga must exist');
|
assert(index != -1, 'The manga must exist');
|
||||||
|
|
||||||
final manga = state.mangas[index];
|
final manga = state.mangas[index];
|
||||||
if (manga.chaptersTotal != null && manga.chaptersRead + 1 > manga.chaptersTotal!) return;
|
if (manga.chaptersTotal != null &&
|
||||||
|
manga.chaptersRead + 1 > manga.chaptersTotal!) return;
|
||||||
|
|
||||||
final newList = List<MangaTrackingData>.from(state.mangas);
|
final newList = List<MangaTrackingData>.from(state.mangas);
|
||||||
final newManga = manga.copyWith(
|
final newManga = manga.copyWith(
|
||||||
@ -195,7 +226,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().updateManga(newManga);
|
await GetIt.I.get<DatabaseService>().updateManga(newManga);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangaDecremented(MangaChapterDecrementedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onMangaDecremented(
|
||||||
|
MangaChapterDecrementedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
final index = state.mangas.indexWhere((item) => item.id == event.id);
|
final index = state.mangas.indexWhere((item) => item.id == event.id);
|
||||||
if (index == -1) return;
|
if (index == -1) return;
|
||||||
|
|
||||||
@ -222,7 +256,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().updateManga(newManga);
|
await GetIt.I.get<DatabaseService>().updateManga(newManga);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimeUpdated(AnimeUpdatedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onAnimeUpdated(
|
||||||
|
AnimeUpdatedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
final index = _animes.indexWhere((anime) => anime.id == event.anime.id);
|
final index = _animes.indexWhere((anime) => anime.id == event.anime.id);
|
||||||
assert(index != -1, 'The anime must exist');
|
assert(index != -1, 'The anime must exist');
|
||||||
|
|
||||||
@ -235,7 +272,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangaUpdated(MangaUpdatedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onMangaUpdated(
|
||||||
|
MangaUpdatedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
final index = _mangas.indexWhere((manga) => manga.id == event.manga.id);
|
final index = _mangas.indexWhere((manga) => manga.id == event.manga.id);
|
||||||
assert(index != -1, 'The manga must exist');
|
assert(index != -1, 'The manga must exist');
|
||||||
|
|
||||||
@ -248,7 +288,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimeRemoved(AnimeRemovedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onAnimeRemoved(
|
||||||
|
AnimeRemovedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
animes: List.from(
|
animes: List.from(
|
||||||
@ -266,7 +309,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().deleteAnime(event.id);
|
await GetIt.I.get<DatabaseService>().deleteAnime(event.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangaRemoved(MangaRemovedEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onMangaRemoved(
|
||||||
|
MangaRemovedEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
mangas: List.from(
|
mangas: List.from(
|
||||||
@ -284,7 +330,10 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
|||||||
await GetIt.I.get<DatabaseService>().deleteManga(event.id);
|
await GetIt.I.get<DatabaseService>().deleteManga(event.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onButtonVisibilityToggled(AddButtonVisibilitySetEvent event, Emitter<AnimeListState> emit) async {
|
Future<void> _onButtonVisibilityToggled(
|
||||||
|
AddButtonVisibilitySetEvent event,
|
||||||
|
Emitter<AnimeListState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
buttonVisibility: event.state,
|
buttonVisibility: event.state,
|
||||||
|
@ -22,7 +22,10 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
on<ResultTappedEvent>(_onResultTapped);
|
on<ResultTappedEvent>(_onResultTapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onRequested(AnimeSearchRequestedEvent event, Emitter<AnimeSearchState> emit) async {
|
Future<void> _onRequested(
|
||||||
|
AnimeSearchRequestedEvent event,
|
||||||
|
Emitter<AnimeSearchState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
@ -39,7 +42,10 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onQueryChanged(SearchQueryChangedEvent event, Emitter<AnimeSearchState> emit) async {
|
Future<void> _onQueryChanged(
|
||||||
|
SearchQueryChangedEvent event,
|
||||||
|
Emitter<AnimeSearchState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
searchQuery: event.query,
|
searchQuery: event.query,
|
||||||
@ -47,7 +53,10 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onQuerySubmitted(SearchQuerySubmittedEvent event, Emitter<AnimeSearchState> emit) async {
|
Future<void> _onQuerySubmitted(
|
||||||
|
SearchQuerySubmittedEvent event,
|
||||||
|
Emitter<AnimeSearchState> emit,
|
||||||
|
) async {
|
||||||
if (state.searchQuery.isEmpty) return;
|
if (state.searchQuery.isEmpty) return;
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
@ -65,13 +74,17 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
working: false,
|
working: false,
|
||||||
searchResults: result.map((Anime anime) => SearchResult(
|
searchResults: result
|
||||||
|
.map(
|
||||||
|
(Anime anime) => SearchResult(
|
||||||
anime.title,
|
anime.title,
|
||||||
anime.malId.toString(),
|
anime.malId.toString(),
|
||||||
anime.episodes,
|
anime.episodes,
|
||||||
anime.imageUrl,
|
anime.imageUrl,
|
||||||
anime.synopsis ?? '',
|
anime.synopsis ?? '',
|
||||||
),).toList(),
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -83,22 +96,29 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
working: false,
|
working: false,
|
||||||
searchResults: result.map((Manga manga) => SearchResult(
|
searchResults: result
|
||||||
|
.map(
|
||||||
|
(Manga manga) => SearchResult(
|
||||||
manga.title,
|
manga.title,
|
||||||
manga.malId.toString(),
|
manga.malId.toString(),
|
||||||
manga.chapters,
|
manga.chapters,
|
||||||
manga.imageUrl,
|
manga.imageUrl,
|
||||||
manga.synopsis ?? '',
|
manga.synopsis ?? '',
|
||||||
),).toList(),
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onResultTapped(ResultTappedEvent event, Emitter<AnimeSearchState> emit) async {
|
Future<void> _onResultTapped(
|
||||||
|
ResultTappedEvent event,
|
||||||
|
Emitter<AnimeSearchState> emit,
|
||||||
|
) async {
|
||||||
GetIt.I.get<list.AnimeListBloc>().add(
|
GetIt.I.get<list.AnimeListBloc>().add(
|
||||||
state.trackingType == TrackingMediumType.anime ?
|
state.trackingType == TrackingMediumType.anime
|
||||||
list.AnimeAddedEvent(
|
? list.AnimeAddedEvent(
|
||||||
AnimeTrackingData(
|
AnimeTrackingData(
|
||||||
event.result.id,
|
event.result.id,
|
||||||
MediumTrackingState.ongoing,
|
MediumTrackingState.ongoing,
|
||||||
@ -107,8 +127,8 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
|
|||||||
event.result.total,
|
event.result.total,
|
||||||
event.result.thumbnailUrl,
|
event.result.thumbnailUrl,
|
||||||
),
|
),
|
||||||
) :
|
)
|
||||||
list.MangaAddedEvent(
|
: list.MangaAddedEvent(
|
||||||
MangaTrackingData(
|
MangaTrackingData(
|
||||||
event.result.id,
|
event.result.id,
|
||||||
MediumTrackingState.ongoing,
|
MediumTrackingState.ongoing,
|
||||||
|
@ -21,7 +21,10 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
|
|||||||
on<ItemRemovedEvent>(_onItemRemoved);
|
on<ItemRemovedEvent>(_onItemRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onAnimeRequested(AnimeDetailsRequestedEvent event, Emitter<DetailsState> emit) async {
|
Future<void> _onAnimeRequested(
|
||||||
|
AnimeDetailsRequestedEvent event,
|
||||||
|
Emitter<DetailsState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
trackingType: TrackingMediumType.anime,
|
trackingType: TrackingMediumType.anime,
|
||||||
@ -36,7 +39,10 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onMangaRequested(MangaDetailsRequestedEvent event, Emitter<DetailsState> emit) async {
|
Future<void> _onMangaRequested(
|
||||||
|
MangaDetailsRequestedEvent event,
|
||||||
|
Emitter<DetailsState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
trackingType: TrackingMediumType.manga,
|
trackingType: TrackingMediumType.manga,
|
||||||
@ -51,7 +57,10 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onDetailsUpdated(DetailsUpdatedEvent event, Emitter<DetailsState> emit) async {
|
Future<void> _onDetailsUpdated(
|
||||||
|
DetailsUpdatedEvent event,
|
||||||
|
Emitter<DetailsState> emit,
|
||||||
|
) async {
|
||||||
if (state.trackingType == TrackingMediumType.anime) {
|
if (state.trackingType == TrackingMediumType.anime) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
@ -59,7 +68,9 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
await GetIt.I.get<DatabaseService>().updateAnime(event.data as AnimeTrackingData);
|
await GetIt.I
|
||||||
|
.get<DatabaseService>()
|
||||||
|
.updateAnime(event.data as AnimeTrackingData);
|
||||||
|
|
||||||
GetIt.I.get<AnimeListBloc>().add(
|
GetIt.I.get<AnimeListBloc>().add(
|
||||||
AnimeUpdatedEvent(event.data as AnimeTrackingData),
|
AnimeUpdatedEvent(event.data as AnimeTrackingData),
|
||||||
@ -71,7 +82,9 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
await GetIt.I.get<DatabaseService>().updateManga(event.data as MangaTrackingData);
|
await GetIt.I
|
||||||
|
.get<DatabaseService>()
|
||||||
|
.updateManga(event.data as MangaTrackingData);
|
||||||
|
|
||||||
GetIt.I.get<AnimeListBloc>().add(
|
GetIt.I.get<AnimeListBloc>().add(
|
||||||
MangaUpdatedEvent(event.data as MangaTrackingData),
|
MangaUpdatedEvent(event.data as MangaTrackingData),
|
||||||
@ -79,7 +92,10 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onItemRemoved(ItemRemovedEvent event, Emitter<DetailsState> emit) async {
|
Future<void> _onItemRemoved(
|
||||||
|
ItemRemovedEvent event,
|
||||||
|
Emitter<DetailsState> emit,
|
||||||
|
) async {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
data: null,
|
data: null,
|
||||||
|
@ -13,14 +13,20 @@ class NavigationBloc extends Bloc<NavigationEvent, NavigationState> {
|
|||||||
}
|
}
|
||||||
final GlobalKey<NavigatorState> navigationKey;
|
final GlobalKey<NavigatorState> navigationKey;
|
||||||
|
|
||||||
Future<void> _onPushedNamed(PushedNamedEvent event, Emitter<NavigationState> emit) async {
|
Future<void> _onPushedNamed(
|
||||||
|
PushedNamedEvent event,
|
||||||
|
Emitter<NavigationState> emit,
|
||||||
|
) async {
|
||||||
await navigationKey.currentState!.pushNamed(
|
await navigationKey.currentState!.pushNamed(
|
||||||
event.destination.path,
|
event.destination.path,
|
||||||
arguments: event.destination.arguments,
|
arguments: event.destination.arguments,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onPushedNamedAndRemoveUntil(PushedNamedAndRemoveUntilEvent event, Emitter<NavigationState> emit) async {
|
Future<void> _onPushedNamedAndRemoveUntil(
|
||||||
|
PushedNamedAndRemoveUntilEvent event,
|
||||||
|
Emitter<NavigationState> emit,
|
||||||
|
) async {
|
||||||
await navigationKey.currentState!.pushNamedAndRemoveUntil(
|
await navigationKey.currentState!.pushNamedAndRemoveUntil(
|
||||||
event.destination.path,
|
event.destination.path,
|
||||||
event.predicate,
|
event.predicate,
|
||||||
@ -28,14 +34,20 @@ class NavigationBloc extends Bloc<NavigationEvent, NavigationState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onPushedNamedReplaceEvent(PushedNamedReplaceEvent event, Emitter<NavigationState> emit) async {
|
Future<void> _onPushedNamedReplaceEvent(
|
||||||
|
PushedNamedReplaceEvent event,
|
||||||
|
Emitter<NavigationState> emit,
|
||||||
|
) async {
|
||||||
await navigationKey.currentState!.pushReplacementNamed(
|
await navigationKey.currentState!.pushReplacementNamed(
|
||||||
event.destination.path,
|
event.destination.path,
|
||||||
arguments: event.destination.arguments,
|
arguments: event.destination.arguments,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onPoppedRoute(PoppedRouteEvent event, Emitter<NavigationState> emit) async {
|
Future<void> _onPoppedRoute(
|
||||||
|
PoppedRouteEvent event,
|
||||||
|
Emitter<NavigationState> emit,
|
||||||
|
) async {
|
||||||
navigationKey.currentState!.pop();
|
navigationKey.currentState!.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,9 @@ part of 'navigation_bloc.dart';
|
|||||||
|
|
||||||
class NavigationDestination {
|
class NavigationDestination {
|
||||||
const NavigationDestination(
|
const NavigationDestination(
|
||||||
this.path,
|
this.path, {
|
||||||
{
|
|
||||||
this.arguments,
|
this.arguments,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
final String path;
|
final String path;
|
||||||
final Object? arguments;
|
final Object? arguments;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ class AboutPage extends StatelessWidget {
|
|||||||
'AniTrack',
|
'AniTrack',
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
),
|
),
|
||||||
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await launchUrl(
|
await launchUrl(
|
||||||
|
@ -16,7 +16,7 @@ class AnimeListPage extends StatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
|
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
|
||||||
builder: (_) => AnimeListPage(),
|
builder: (_) => const AnimeListPage(),
|
||||||
settings: const RouteSettings(
|
settings: const RouteSettings(
|
||||||
name: animeListRoute,
|
name: animeListRoute,
|
||||||
),
|
),
|
||||||
@ -39,7 +39,8 @@ class AnimeListPageState extends State<AnimeListPage> {
|
|||||||
void _onAnimeListScrolled() {
|
void _onAnimeListScrolled() {
|
||||||
//print(_animeScrollController.position.maxScrollExtent);
|
//print(_animeScrollController.position.maxScrollExtent);
|
||||||
final bloc = GetIt.I.get<AnimeListBloc>();
|
final bloc = GetIt.I.get<AnimeListBloc>();
|
||||||
if (_animeScrollController.offset + 20 >= _animeScrollController.position.maxScrollExtent) {
|
if (_animeScrollController.offset + 20 >=
|
||||||
|
_animeScrollController.position.maxScrollExtent) {
|
||||||
if (bloc.state.buttonVisibility) {
|
if (bloc.state.buttonVisibility) {
|
||||||
bloc.add(
|
bloc.add(
|
||||||
AddButtonVisibilitySetEvent(false),
|
AddButtonVisibilitySetEvent(false),
|
||||||
@ -56,12 +57,16 @@ class AnimeListPageState extends State<AnimeListPage> {
|
|||||||
|
|
||||||
String _getPageTitle(TrackingMediumType type) {
|
String _getPageTitle(TrackingMediumType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TrackingMediumType.anime: return 'Anime';
|
case TrackingMediumType.anime:
|
||||||
case TrackingMediumType.manga: return 'Manga';
|
return 'Anime';
|
||||||
|
case TrackingMediumType.manga:
|
||||||
|
return 'Manga';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<PopupMenuItem<MediumTrackingState>> _getPopupButtonItems(TrackingMediumType type) {
|
List<PopupMenuItem<MediumTrackingState>> _getPopupButtonItems(
|
||||||
|
TrackingMediumType type,
|
||||||
|
) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem<MediumTrackingState>(
|
PopupMenuItem<MediumTrackingState>(
|
||||||
value: MediumTrackingState.ongoing,
|
value: MediumTrackingState.ongoing,
|
||||||
@ -145,7 +150,6 @@ class AnimeListPageState extends State<AnimeListPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.info),
|
leading: const Icon(Icons.info),
|
||||||
title: const Text('About'),
|
title: const Text('About'),
|
||||||
@ -266,13 +270,12 @@ class AnimeListPageState extends State<AnimeListPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
floatingActionButton: BlocBuilder<AnimeListBloc, AnimeListState>(
|
floatingActionButton: BlocBuilder<AnimeListBloc, AnimeListState>(
|
||||||
buildWhen: (prev, next) => prev.buttonVisibility != next.buttonVisibility,
|
buildWhen: (prev, next) =>
|
||||||
|
prev.buttonVisibility != next.buttonVisibility,
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return AnimatedScale(
|
return AnimatedScale(
|
||||||
duration: const Duration(milliseconds: 250),
|
duration: const Duration(milliseconds: 250),
|
||||||
scale: state.buttonVisibility ?
|
scale: state.buttonVisibility ? 1 : 0,
|
||||||
1 :
|
|
||||||
0,
|
|
||||||
curve: Curves.easeInOutQuint,
|
curve: Curves.easeInOutQuint,
|
||||||
child: FloatingActionButton(
|
child: FloatingActionButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -287,15 +290,14 @@ class AnimeListPageState extends State<AnimeListPage> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
bottomNavigationBar: BottomBar(
|
bottomNavigationBar: BottomBar(
|
||||||
selectedIndex: state.trackingType == TrackingMediumType.anime ?
|
selectedIndex:
|
||||||
0 :
|
state.trackingType == TrackingMediumType.anime ? 0 : 1,
|
||||||
1,
|
|
||||||
onTap: (int index) {
|
onTap: (int index) {
|
||||||
context.read<AnimeListBloc>().add(
|
context.read<AnimeListBloc>().add(
|
||||||
AnimeTrackingTypeChanged(
|
AnimeTrackingTypeChanged(
|
||||||
index == 0 ?
|
index == 0
|
||||||
TrackingMediumType.anime :
|
? TrackingMediumType.anime
|
||||||
TrackingMediumType.manga,
|
: TrackingMediumType.manga,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ class AnimeSearchPage extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
state.trackingType == TrackingMediumType.anime ?
|
state.trackingType == TrackingMediumType.anime
|
||||||
'Anime Search' :
|
? 'Anime Search'
|
||||||
'Manga Search',
|
: 'Manga Search',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
@ -50,7 +50,6 @@ class AnimeSearchPage extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if (state.working)
|
if (state.working)
|
||||||
const Expanded(
|
const Expanded(
|
||||||
child: Align(
|
child: Align(
|
||||||
|
@ -30,19 +30,19 @@ class DetailsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
body: BlocBuilder<DetailsBloc, DetailsState>(
|
body: BlocBuilder<DetailsBloc, DetailsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return state.data == null ?
|
return state.data == null
|
||||||
Container() :
|
? Container()
|
||||||
Padding(
|
: Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [AnimeCoverImage(
|
children: [
|
||||||
|
AnimeCoverImage(
|
||||||
url: state.data!.thumbnailUrl,
|
url: state.data!.thumbnailUrl,
|
||||||
hero: state.data!.id,
|
hero: state.data!.id,
|
||||||
),
|
),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(
|
padding: const EdgeInsets.only(
|
||||||
@ -55,24 +55,29 @@ class DetailsPage extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
state.data!.title,
|
state.data!.title,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style:
|
||||||
|
Theme.of(context).textTheme.titleLarge,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result = await showDialog<bool>(
|
final result = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text('Remove "${state.data!.title}"?'),
|
title: Text(
|
||||||
content: Text('Are you sure you want to remove "${state.data!.title}" from the list?'),
|
'Remove "${state.data!.title}"?',
|
||||||
|
),
|
||||||
|
content: Text(
|
||||||
|
'Are you sure you want to remove "${state.data!.title}" from the list?',
|
||||||
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop(true);
|
Navigator.of(context)
|
||||||
|
.pop(true);
|
||||||
},
|
},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
foregroundColor: Colors.red,
|
foregroundColor: Colors.red,
|
||||||
@ -81,7 +86,8 @@ class DetailsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop(false);
|
Navigator.of(context)
|
||||||
|
.pop(false);
|
||||||
},
|
},
|
||||||
child: const Text('Cancel'),
|
child: const Text('Cancel'),
|
||||||
),
|
),
|
||||||
@ -108,28 +114,31 @@ class DetailsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: DropdownSelector<MediumTrackingState>(
|
child: DropdownSelector<MediumTrackingState>(
|
||||||
title: state.trackingType == TrackingMediumType.anime ?
|
title: state.trackingType == TrackingMediumType.anime
|
||||||
'Watch state' :
|
? 'Watch state'
|
||||||
'Read state',
|
: 'Read state',
|
||||||
onChanged: (MediumTrackingState newState) {
|
onChanged: (MediumTrackingState newState) {
|
||||||
if (state.trackingType == TrackingMediumType.anime) {
|
if (state.trackingType ==
|
||||||
|
TrackingMediumType.anime) {
|
||||||
context.read<DetailsBloc>().add(
|
context.read<DetailsBloc>().add(
|
||||||
DetailsUpdatedEvent(
|
DetailsUpdatedEvent(
|
||||||
(state.data! as AnimeTrackingData).copyWith(
|
(state.data! as AnimeTrackingData)
|
||||||
|
.copyWith(
|
||||||
state: newState,
|
state: newState,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else if (state.trackingType == TrackingMediumType.manga) {
|
} else if (state.trackingType ==
|
||||||
|
TrackingMediumType.manga) {
|
||||||
context.read<DetailsBloc>().add(
|
context.read<DetailsBloc>().add(
|
||||||
DetailsUpdatedEvent(
|
DetailsUpdatedEvent(
|
||||||
(state.data! as MangaTrackingData).copyWith(
|
(state.data! as MangaTrackingData)
|
||||||
|
.copyWith(
|
||||||
state: newState,
|
state: newState,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -139,33 +148,37 @@ class DetailsPage extends StatelessWidget {
|
|||||||
values: [
|
values: [
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.ongoing,
|
MediumTrackingState.ongoing,
|
||||||
MediumTrackingState.ongoing.toNameString(state.trackingType),
|
MediumTrackingState.ongoing
|
||||||
|
.toNameString(state.trackingType),
|
||||||
),
|
),
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.completed,
|
MediumTrackingState.completed,
|
||||||
MediumTrackingState.completed.toNameString(state.trackingType),
|
MediumTrackingState.completed
|
||||||
|
.toNameString(state.trackingType),
|
||||||
),
|
),
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.planned,
|
MediumTrackingState.planned,
|
||||||
MediumTrackingState.planned.toNameString(state.trackingType),
|
MediumTrackingState.planned
|
||||||
|
.toNameString(state.trackingType),
|
||||||
),
|
),
|
||||||
SelectorItem(
|
SelectorItem(
|
||||||
MediumTrackingState.dropped,
|
MediumTrackingState.dropped,
|
||||||
MediumTrackingState.dropped.toNameString(state.trackingType),
|
MediumTrackingState.dropped
|
||||||
|
.toNameString(state.trackingType),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
initialValue: state.data!.state,
|
initialValue: state.data!.state,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
child: IntegerInput(
|
child: IntegerInput(
|
||||||
labelText: state.trackingType == TrackingMediumType.anime ?
|
labelText:
|
||||||
'Episodes' :
|
state.trackingType == TrackingMediumType.anime
|
||||||
'Chapters',
|
? 'Episodes'
|
||||||
|
: 'Chapters',
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
switch (state.trackingType) {
|
switch (state.trackingType) {
|
||||||
case TrackingMediumType.anime:
|
case TrackingMediumType.anime:
|
||||||
@ -190,12 +203,13 @@ class DetailsPage extends StatelessWidget {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
initialValue: state.trackingType == TrackingMediumType.anime ?
|
initialValue: state.trackingType ==
|
||||||
(state.data! as AnimeTrackingData).episodesWatched :
|
TrackingMediumType.anime
|
||||||
(state.data! as MangaTrackingData).chaptersRead,
|
? (state.data! as AnimeTrackingData)
|
||||||
|
.episodesWatched
|
||||||
|
: (state.data! as MangaTrackingData).chaptersRead,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if (state.trackingType == TrackingMediumType.manga)
|
if (state.trackingType == TrackingMediumType.manga)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
@ -213,7 +227,11 @@ class DetailsPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
initialValue: (GetIt.I.get<DetailsBloc>().state.data! as MangaTrackingData).volumesOwned,
|
initialValue: (GetIt.I
|
||||||
|
.get<DetailsBloc>()
|
||||||
|
.state
|
||||||
|
.data! as MangaTrackingData)
|
||||||
|
.volumesOwned,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -76,7 +76,8 @@ class DropdownSelectorState<T> extends State<DropdownSelector<T>> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
index = widget.values.indexWhere((item) => item.value == widget.initialValue);
|
index =
|
||||||
|
widget.values.indexWhere((item) => item.value == widget.initialValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -99,7 +100,8 @@ class DropdownSelectorState<T> extends State<DropdownSelector<T>> {
|
|||||||
if (result == widget.values[index].value) return;
|
if (result == widget.values[index].value) return;
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
index = widget.values.indexWhere((item) => item.value == result);
|
index =
|
||||||
|
widget.values.indexWhere((item) => item.value == result);
|
||||||
});
|
});
|
||||||
|
|
||||||
widget.onChanged(result);
|
widget.onChanged(result);
|
||||||
|
@ -28,7 +28,7 @@ class GridItemState extends State<GridItem> {
|
|||||||
onHorizontalDragUpdate: (details) {
|
onHorizontalDragUpdate: (details) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_offset += details.delta.dx;
|
_offset += details.delta.dx;
|
||||||
_translationX = 160 / (1 + exp(-1 * (1/30) * _offset)) - 80;
|
_translationX = 160 / (1 + exp(-1 * (1 / 30) * _offset)) - 80;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onHorizontalDragEnd: (_) {
|
onHorizontalDragEnd: (_) {
|
||||||
|
@ -48,15 +48,14 @@ class AnimeCoverImage extends StatelessWidget {
|
|||||||
child: DecoratedBox(
|
child: DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: cached ?
|
image: cached
|
||||||
CachedNetworkImageProvider(url) as ImageProvider :
|
? CachedNetworkImageProvider(url) as ImageProvider
|
||||||
NetworkImage(url),
|
: NetworkImage(url),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if (extra != null)
|
if (extra != null)
|
||||||
Positioned(
|
Positioned(
|
||||||
left: 0,
|
left: 0,
|
||||||
|
@ -59,7 +59,6 @@ class IntegerInputState extends State<IntegerInput> {
|
|||||||
},
|
},
|
||||||
child: const Icon(Icons.remove),
|
child: const Icon(Icons.remove),
|
||||||
),
|
),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
@ -84,7 +83,6 @@ class IntegerInputState extends State<IntegerInput> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_value++;
|
_value++;
|
||||||
|
@ -66,9 +66,9 @@ class ListItem extends StatelessWidget {
|
|||||||
return Container();
|
return Container();
|
||||||
},
|
},
|
||||||
color: Theme.of(context).scaffoldBackgroundColor,
|
color: Theme.of(context).scaffoldBackgroundColor,
|
||||||
direction: onRightSwipe != null && onLeftSwipe != null ?
|
direction: onRightSwipe != null && onLeftSwipe != null
|
||||||
SwipeDirection.horizontal :
|
? SwipeDirection.horizontal
|
||||||
SwipeDirection.none,
|
: SwipeDirection.none,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -81,7 +81,6 @@ class ListItem extends StatelessWidget {
|
|||||||
extra: imageExtra,
|
extra: imageExtra,
|
||||||
url: thumbnailUrl,
|
url: thumbnailUrl,
|
||||||
),
|
),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
@ -97,7 +96,6 @@ class ListItem extends StatelessWidget {
|
|||||||
softWrap: true,
|
softWrap: true,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
|
||||||
...extra,
|
...extra,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user