feat(meta): Implement manga tracking
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:anitrack/src/data/anime.dart';
|
||||
import 'package:anitrack/src/data/manga.dart';
|
||||
import 'package:anitrack/src/data/type.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_list_bloc.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_search_bloc.dart';
|
||||
@@ -24,6 +25,79 @@ class AnimeListPage extends StatelessWidget {
|
||||
case TrackingMediumType.manga: return 'Manga';
|
||||
}
|
||||
}
|
||||
|
||||
Widget _getPopupButton(BuildContext context, AnimeListState state) {
|
||||
switch (state.trackingType) {
|
||||
case TrackingMediumType.anime:
|
||||
return PopupMenuButton(
|
||||
icon: Icon(
|
||||
Icons.filter_list,
|
||||
),
|
||||
initialValue: state.animeFilterState,
|
||||
onSelected: (filterState) {
|
||||
context.read<AnimeListBloc>().add(
|
||||
AnimeFilterChangedEvent(filterState),
|
||||
);
|
||||
},
|
||||
itemBuilder: (_) => [
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.watching,
|
||||
child: Text('Watching'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.completed,
|
||||
child: Text('Completed'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.planToWatch,
|
||||
child: Text('Plan to watch'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.dropped,
|
||||
child: Text('Dropped'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.all,
|
||||
child: Text('All'),
|
||||
),
|
||||
],
|
||||
);
|
||||
case TrackingMediumType.manga:
|
||||
return PopupMenuButton(
|
||||
icon: Icon(
|
||||
Icons.filter_list,
|
||||
),
|
||||
initialValue: state.mangaFilterState,
|
||||
onSelected: (filterState) {
|
||||
context.read<AnimeListBloc>().add(
|
||||
MangaFilterChangedEvent(filterState),
|
||||
);
|
||||
},
|
||||
itemBuilder: (_) => [
|
||||
const PopupMenuItem<MangaTrackingState>(
|
||||
value: MangaTrackingState.reading,
|
||||
child: Text('Reading'),
|
||||
),
|
||||
const PopupMenuItem<MangaTrackingState>(
|
||||
value: MangaTrackingState.completed,
|
||||
child: Text('Completed'),
|
||||
),
|
||||
const PopupMenuItem<MangaTrackingState>(
|
||||
value: MangaTrackingState.planToWatch,
|
||||
child: Text('Plan to watch'),
|
||||
),
|
||||
const PopupMenuItem<MangaTrackingState>(
|
||||
value: MangaTrackingState.dropped,
|
||||
child: Text('Dropped'),
|
||||
),
|
||||
const PopupMenuItem<MangaTrackingState>(
|
||||
value: MangaTrackingState.all,
|
||||
child: Text('All'),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -35,39 +109,7 @@ class AnimeListPage extends StatelessWidget {
|
||||
_getPageTitle(state.trackingType)
|
||||
),
|
||||
actions: [
|
||||
PopupMenuButton(
|
||||
icon: Icon(
|
||||
Icons.filter_list,
|
||||
),
|
||||
initialValue: state.filterState,
|
||||
onSelected: (filterState) {
|
||||
context.read<AnimeListBloc>().add(
|
||||
AnimeFilterChangedEvent(filterState),
|
||||
);
|
||||
},
|
||||
itemBuilder: (_) => [
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.watching,
|
||||
child: Text('Watching'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.completed,
|
||||
child: Text('Completed'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.planToWatch,
|
||||
child: Text('Plan to watch'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.dropped,
|
||||
child: Text('Dropped'),
|
||||
),
|
||||
const PopupMenuItem<AnimeTrackingState>(
|
||||
value: AnimeTrackingState.all,
|
||||
child: Text('All'),
|
||||
),
|
||||
],
|
||||
),
|
||||
_getPopupButton(context, state),
|
||||
],
|
||||
),
|
||||
body: PageView(
|
||||
@@ -77,8 +119,8 @@ class AnimeListPage extends StatelessWidget {
|
||||
itemCount: state.animes.length,
|
||||
itemBuilder: (context, index) {
|
||||
final anime = state.animes[index];
|
||||
if (state.filterState != AnimeTrackingState.all) {
|
||||
if (anime.state != state.filterState) return Container();
|
||||
if (state.animeFilterState != AnimeTrackingState.all) {
|
||||
if (anime.state != state.animeFilterState) return Container();
|
||||
}
|
||||
|
||||
return ListItem(
|
||||
@@ -103,13 +145,42 @@ class AnimeListPage extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
Placeholder(),
|
||||
ListView.builder(
|
||||
itemCount: state.mangas.length,
|
||||
itemBuilder: (context, index) {
|
||||
final manga = state.mangas[index];
|
||||
if (state.mangaFilterState != MangaTrackingState.all) {
|
||||
if (manga.state != state.mangaFilterState) return Container();
|
||||
}
|
||||
|
||||
return ListItem(
|
||||
title: manga.title,
|
||||
thumbnailUrl: manga.thumbnailUrl,
|
||||
extra: [
|
||||
Text(
|
||||
'${manga.chaptersRead}/${manga.chaptersTotal ?? "???"}',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
onLeftSwipe: () {
|
||||
context.read<AnimeListBloc>().add(
|
||||
MangaChapterDecrementedEvent(state.mangas[index].id),
|
||||
);
|
||||
},
|
||||
onRightSwipe: () {
|
||||
context.read<AnimeListBloc>().add(
|
||||
MangaChapterIncrementedEvent(state.mangas[index].id),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
context.read<AnimeSearchBloc>().add(
|
||||
AnimeSearchRequestedEvent(),
|
||||
AnimeSearchRequestedEvent(state.trackingType),
|
||||
);
|
||||
},
|
||||
tooltip: 'Increment',
|
||||
@@ -120,7 +191,6 @@ class AnimeListPage extends StatelessWidget {
|
||||
0 :
|
||||
1,
|
||||
onTap: (int index) {
|
||||
_controller.jumpToPage(index);
|
||||
context.read<AnimeListBloc>().add(
|
||||
AnimeTrackingTypeChanged(
|
||||
index == 0 ?
|
||||
@@ -128,6 +198,8 @@ class AnimeListPage extends StatelessWidget {
|
||||
TrackingMediumType.manga,
|
||||
),
|
||||
);
|
||||
|
||||
_controller.jumpToPage(index);
|
||||
},
|
||||
items: <BottomBarItem>[
|
||||
BottomBarItem(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:anitrack/src/data/anime.dart';
|
||||
import 'package:anitrack/src/data/type.dart';
|
||||
import 'package:anitrack/src/ui/bloc/anime_search_bloc.dart';
|
||||
import 'package:anitrack/src/ui/constants.dart';
|
||||
import 'package:anitrack/src/ui/widgets/list_item.dart';
|
||||
@@ -20,7 +21,11 @@ class AnimeSearchPage extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Anime Search'),
|
||||
title: Text(
|
||||
state.trackingType == TrackingMediumType.anime ?
|
||||
'Anime Search' :
|
||||
'Manga Search',
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
@@ -60,7 +65,7 @@ class AnimeSearchPage extends StatelessWidget {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
context.read<AnimeSearchBloc>().add(
|
||||
AnimeAddedEvent(item),
|
||||
ResultTappedEvent(item),
|
||||
);
|
||||
},
|
||||
child: ListItem(
|
||||
|
||||
Reference in New Issue
Block a user