chore: Format code

This commit is contained in:
2026-05-10 23:14:57 +02:00
parent dd6d4a204d
commit 2c279a0150
14 changed files with 282 additions and 241 deletions

View File

@@ -123,7 +123,10 @@ class DatabaseService {
);
}
Future<AnimeTrackingData> incrementAnimeWatchCounter(AnimeTrackingData data, int value) async {
Future<AnimeTrackingData> incrementAnimeWatchCounter(
AnimeTrackingData data,
int value,
) async {
final result = await _db.rawQuery(
'UPDATE $animeTable SET episodesWatched = episodesWatched + $value WHERE id = ? RETURNING *',
[
@@ -171,7 +174,10 @@ class DatabaseService {
);
}
Future<MangaTrackingData> incrementMangaReadChapters(MangaTrackingData data, int value) async {
Future<MangaTrackingData> incrementMangaReadChapters(
MangaTrackingData data,
int value,
) async {
final result = await _db.rawQuery(
'UPDATE $mangaTable SET episodesWatched = chaptersRead + $value WHERE id = ? RETURNING *',
[

View File

@@ -31,10 +31,12 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
}
/// Internal anime state
final List<AnimeTrackingData> _animes =
List<AnimeTrackingData>.empty(growable: true);
final List<MangaTrackingData> _mangas =
List<MangaTrackingData>.empty(growable: true);
final List<AnimeTrackingData> _animes = List<AnimeTrackingData>.empty(
growable: true,
);
final List<MangaTrackingData> _mangas = List<MangaTrackingData>.empty(
growable: true,
);
List<AnimeTrackingData> get unfilteredAnime => _animes;
@@ -69,7 +71,7 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
if (event.checkIfExists) {
final shouldAdd =
_animes.firstWhereOrNull((element) => element.id == event.data.id) ==
null;
null;
if (shouldAdd) {
_animes.add(event.data);
}
@@ -96,7 +98,7 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
if (event.checkIfExists) {
final shouldAdd =
_mangas.firstWhereOrNull((element) => element.id == event.data.id) ==
null;
null;
if (shouldAdd) {
_mangas.add(event.data);
}
@@ -120,9 +122,12 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
final anime = state.animes[index];
if (anime.episodesTotal != null &&
anime.episodesWatched + 1 > anime.episodesTotal!) return;
anime.episodesWatched + 1 > anime.episodesTotal!)
return;
final newAnime = await GetIt.I.get<DatabaseService>().incrementAnimeWatchCounter(anime, 1);
final newAnime = await GetIt.I
.get<DatabaseService>()
.incrementAnimeWatchCounter(anime, 1);
final newList = List<AnimeTrackingData>.from(state.animes);
newList[index] = newAnime;
emit(
@@ -142,8 +147,9 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
final anime = state.animes[index];
if (anime.episodesWatched - 1 < 0) return;
final newAnime = await GetIt.I.get<DatabaseService>().incrementAnimeWatchCounter(anime, -1);
final newAnime = await GetIt.I
.get<DatabaseService>()
.incrementAnimeWatchCounter(anime, -1);
final newList = List<AnimeTrackingData>.from(state.animes);
newList[index] = newAnime;
emit(
@@ -217,9 +223,12 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
final manga = state.mangas[index];
if (manga.chaptersTotal != null &&
manga.chaptersRead + 1 > manga.chaptersTotal!) return;
manga.chaptersRead + 1 > manga.chaptersTotal!)
return;
final newManga = await GetIt.I.get<DatabaseService>().incrementMangaReadChapters(manga, 1);
final newManga = await GetIt.I
.get<DatabaseService>()
.incrementMangaReadChapters(manga, 1);
final newList = List<MangaTrackingData>.from(state.mangas);
newList[index] = newManga;
emit(
@@ -244,7 +253,9 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
final manga = state.mangas[index];
if (manga.chaptersRead - 1 < 0) return;
final newManga = await GetIt.I.get<DatabaseService>().incrementMangaReadChapters(manga, -1);
final newManga = await GetIt.I
.get<DatabaseService>()
.incrementMangaReadChapters(manga, -1);
final newList = List<MangaTrackingData>.from(state.mangas);
newList[index] = newManga;
emit(

View File

@@ -36,10 +36,10 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
);
GetIt.I.get<NavigationBloc>().add(
PushedNamedEvent(
const NavigationDestination(animeSearchRoute),
),
);
PushedNamedEvent(
const NavigationDestination(animeSearchRoute),
),
);
}
Future<void> _onQueryChanged(
@@ -122,34 +122,34 @@ class AnimeSearchBloc extends Bloc<AnimeSearchEvent, AnimeSearchState> {
Emitter<AnimeSearchState> emit,
) async {
GetIt.I.get<list.AnimeListBloc>().add(
state.trackingType == TrackingMediumType.anime
? list.AnimeAddedEvent(
AnimeTrackingData(
event.result.id,
MediumTrackingState.ongoing,
event.result.title,
0,
event.result.total,
event.result.thumbnailUrl,
event.result.isAiring,
event.result.broadcastDay,
),
)
: list.MangaAddedEvent(
MangaTrackingData(
event.result.id,
MediumTrackingState.ongoing,
event.result.title,
0,
0,
event.result.total,
event.result.thumbnailUrl,
),
),
);
state.trackingType == TrackingMediumType.anime
? list.AnimeAddedEvent(
AnimeTrackingData(
event.result.id,
MediumTrackingState.ongoing,
event.result.title,
0,
event.result.total,
event.result.thumbnailUrl,
event.result.isAiring,
event.result.broadcastDay,
),
)
: list.MangaAddedEvent(
MangaTrackingData(
event.result.id,
MediumTrackingState.ongoing,
event.result.title,
0,
0,
event.result.total,
event.result.thumbnailUrl,
),
),
);
GetIt.I.get<NavigationBloc>().add(
PoppedRouteEvent(),
);
PoppedRouteEvent(),
);
}
}

View File

@@ -34,10 +34,10 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
);
GetIt.I.get<NavigationBloc>().add(
PushedNamedEvent(
const NavigationDestination(detailsRoute),
),
);
PushedNamedEvent(
const NavigationDestination(detailsRoute),
),
);
}
Future<void> _onMangaRequested(
@@ -52,10 +52,10 @@ class DetailsBloc extends Bloc<DetailsEvent, DetailsState> {
);
GetIt.I.get<NavigationBloc>().add(
PushedNamedEvent(
const NavigationDestination(detailsRoute),
),
);
PushedNamedEvent(
const NavigationDestination(detailsRoute),
),
);
}
Future<void> _onDetailsUpdated(
@@ -69,13 +69,13 @@ 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(
AnimeUpdatedEvent(event.data as AnimeTrackingData),
);
AnimeUpdatedEvent(event.data as AnimeTrackingData),
);
} else {
emit(
state.copyWith(
@@ -83,13 +83,13 @@ 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(
MangaUpdatedEvent(event.data as MangaTrackingData),
);
MangaUpdatedEvent(event.data as MangaTrackingData),
);
}
}

View File

@@ -105,8 +105,9 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
);
final title = anime.getElement('series_title')!.text;
final totalEpisodes =
int.parse(anime.getElement('series_episodes')!.text);
final totalEpisodes = int.parse(
anime.getElement('series_episodes')!.text,
);
final id = anime.getElement('series_animedb_id')!.text;
print('Waiting 500ms to not hammer Jikan ($title)');
@@ -117,21 +118,21 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
// Add the anime
await GetIt.I.get<DatabaseService>().addAnime(
AnimeTrackingData(
id,
malStatusToTrackingState(
anime.getElement('my_status')!.text,
),
title,
int.parse(anime.getElement('my_watched_episodes')!.text),
// 0 means that MAL does not know
totalEpisodes == 0 ? null : totalEpisodes,
data.imageUrl,
// NOTE: When the calendar gets refreshed, this should also get cleared
true,
null,
),
);
AnimeTrackingData(
id,
malStatusToTrackingState(
anime.getElement('my_status')!.text,
),
title,
int.parse(anime.getElement('my_watched_episodes')!.text),
// 0 means that MAL does not know
totalEpisodes == 0 ? null : totalEpisodes,
data.imageUrl,
// NOTE: When the calendar gets refreshed, this should also get cleared
true,
null,
),
);
}
// Hide the spinner again
@@ -195,19 +196,19 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
// Add the manga
await GetIt.I.get<DatabaseService>().addManga(
MangaTrackingData(
id,
malStatusToTrackingState(
manga.getElement('my_status')!.text,
),
title,
int.parse(manga.getElement('my_read_chapters')!.text),
0,
// 0 means that MAL does not know
totalChapters == 0 ? null : totalChapters,
data.imageUrl,
),
);
MangaTrackingData(
id,
malStatusToTrackingState(
manga.getElement('my_status')!.text,
),
title,
int.parse(manga.getElement('my_read_chapters')!.text),
0,
// 0 means that MAL does not know
totalChapters == 0 ? null : totalChapters,
data.imageUrl,
),
);
}
// Hide the spinner again

View File

@@ -11,11 +11,11 @@ class AboutPage extends StatelessWidget {
});
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
builder: (_) => const AboutPage(),
settings: const RouteSettings(
name: aboutRoute,
),
);
builder: (_) => const AboutPage(),
settings: const RouteSettings(
name: aboutRoute,
),
);
@override
Widget build(BuildContext context) {

View File

@@ -18,11 +18,11 @@ class AnimeListPage extends StatefulWidget {
});
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
builder: (_) => const AnimeListPage(),
settings: const RouteSettings(
name: animeListRoute,
),
);
builder: (_) => const AnimeListPage(),
settings: const RouteSettings(
name: animeListRoute,
),
);
@override
AnimeListPageState createState() => AnimeListPageState();
@@ -107,8 +107,8 @@ class AnimeListPageState extends State<AnimeListPage> {
initialValue: state.animeFilterState,
onSelected: (filterState) {
context.read<AnimeListBloc>().add(
AnimeFilterChangedEvent(filterState),
);
AnimeFilterChangedEvent(filterState),
);
},
itemBuilder: (_) => _getPopupButtonItems(TrackingMediumType.anime),
);
@@ -120,8 +120,8 @@ class AnimeListPageState extends State<AnimeListPage> {
initialValue: state.mangaFilterState,
onSelected: (filterState) {
context.read<AnimeListBloc>().add(
MangaFilterChangedEvent(filterState),
);
MangaFilterChangedEvent(filterState),
);
},
itemBuilder: (_) => _getPopupButtonItems(TrackingMediumType.manga),
);
@@ -164,25 +164,25 @@ class AnimeListPageState extends State<AnimeListPage> {
return GridItem(
minusCallback: () {
context.read<AnimeListBloc>().add(
AnimeEpisodeDecrementedEvent(
anime.id,
),
);
AnimeEpisodeDecrementedEvent(
anime.id,
),
);
},
plusCallback: () {
context.read<AnimeListBloc>().add(
AnimeEpisodeIncrementedEvent(
anime.id,
),
);
AnimeEpisodeIncrementedEvent(
anime.id,
),
);
},
child: AnimeCoverImage(
url: anime.thumbnailUrl,
hero: anime.id,
onTap: () {
context.read<DetailsBloc>().add(
AnimeDetailsRequestedEvent(anime),
);
AnimeDetailsRequestedEvent(anime),
);
},
extra: Align(
alignment: Alignment.centerRight,
@@ -214,25 +214,25 @@ class AnimeListPageState extends State<AnimeListPage> {
return GridItem(
minusCallback: () {
context.read<AnimeListBloc>().add(
MangaChapterDecrementedEvent(
manga.id,
),
);
MangaChapterDecrementedEvent(
manga.id,
),
);
},
plusCallback: () {
context.read<AnimeListBloc>().add(
MangaChapterIncrementedEvent(
manga.id,
),
);
MangaChapterIncrementedEvent(
manga.id,
),
);
},
child: AnimeCoverImage(
hero: manga.id,
url: manga.thumbnailUrl,
onTap: () {
context.read<DetailsBloc>().add(
MangaDetailsRequestedEvent(manga),
);
MangaDetailsRequestedEvent(manga),
);
},
extra: Align(
alignment: Alignment.centerRight,
@@ -263,8 +263,8 @@ class AnimeListPageState extends State<AnimeListPage> {
child: FloatingActionButton(
onPressed: () {
context.read<AnimeSearchBloc>().add(
AnimeSearchRequestedEvent(state.trackingType),
);
AnimeSearchRequestedEvent(state.trackingType),
);
},
tooltip: t.tooltips.addNewItem,
child: const Icon(Icons.add),
@@ -273,16 +273,17 @@ class AnimeListPageState extends State<AnimeListPage> {
},
),
bottomNavigationBar: BottomBar(
selectedIndex:
state.trackingType == TrackingMediumType.anime ? 0 : 1,
selectedIndex: state.trackingType == TrackingMediumType.anime
? 0
: 1,
onTap: (int index) {
context.read<AnimeListBloc>().add(
AnimeTrackingTypeChanged(
index == 0
? TrackingMediumType.anime
: TrackingMediumType.manga,
),
);
AnimeTrackingTypeChanged(
index == 0
? TrackingMediumType.anime
: TrackingMediumType.manga,
),
);
_controller.jumpToPage(index);
},

View File

@@ -12,11 +12,11 @@ class AnimeSearchPage extends StatelessWidget {
});
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
builder: (_) => const AnimeSearchPage(),
settings: const RouteSettings(
name: animeSearchRoute,
),
);
builder: (_) => const AnimeSearchPage(),
settings: const RouteSettings(
name: animeSearchRoute,
),
);
@override
Widget build(BuildContext context) {
@@ -41,13 +41,13 @@ class AnimeSearchPage extends StatelessWidget {
),
onSubmitted: (_) {
context.read<AnimeSearchBloc>().add(
SearchQuerySubmittedEvent(),
);
SearchQuerySubmittedEvent(),
);
},
onChanged: (value) {
context.read<AnimeSearchBloc>().add(
SearchQueryChangedEvent(value),
);
SearchQueryChangedEvent(value),
);
},
),
),
@@ -66,8 +66,8 @@ class AnimeSearchPage extends StatelessWidget {
return InkWell(
onTap: () {
context.read<AnimeSearchBloc>().add(
ResultTappedEvent(item),
);
ResultTappedEvent(item),
);
},
child: ListItem(
title: item.title,

View File

@@ -57,11 +57,11 @@ class CalendarPage extends StatefulWidget {
const CalendarPage({super.key});
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
builder: (_) => const CalendarPage(),
settings: const RouteSettings(
name: calendarRoute,
),
);
builder: (_) => const CalendarPage(),
settings: const RouteSettings(
name: calendarRoute,
),
);
@override
CalendarPageState createState() => CalendarPageState();
@@ -109,11 +109,11 @@ class CalendarPageState extends State<CalendarPage> {
hero: 'calendar_${anime.id}',
onTap: () {
context.read<DetailsBloc>().add(
AnimeDetailsRequestedEvent(
anime,
heroImagePrefix: 'calendar_',
),
);
AnimeDetailsRequestedEvent(
anime,
heroImagePrefix: 'calendar_',
),
);
},
),
);
@@ -183,9 +183,9 @@ class CalendarPageState extends State<CalendarPage> {
actions: [
IconButton(
onPressed: () {
context
.read<CalendarBloc>()
.add(RefreshPerformedEvent());
context.read<CalendarBloc>().add(
RefreshPerformedEvent(),
);
},
icon: const Icon(Icons.refresh),
),

View File

@@ -157,7 +157,10 @@ class DetailsPage extends StatelessWidget {
end: 8,
),
child: Text(
t.details.details.titleJa,
t
.details
.details
.titleJa,
style:
Theme.of(
context,
@@ -173,21 +176,32 @@ class DetailsPage extends StatelessWidget {
end: 8,
),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisSize:
MainAxisSize
.min,
children: [
IconButton(
onPressed: () async {
await Clipboard.setData(
ClipboardData(
text: state.data!.title,
),
);
},
icon: const Icon(Icons.copy),
onPressed: () async {
await Clipboard.setData(
ClipboardData(
text: state
.data!
.title,
),
);
},
icon:
const Icon(
Icons
.copy,
),
),
Expanded(
child: Padding(
padding: const EdgeInsetsGeometry.only(left: 8),
padding:
const EdgeInsetsGeometry.only(
left: 8,
),
child: Text(
state
.data!
@@ -223,13 +237,17 @@ class DetailsPage extends StatelessWidget {
children: [
ElevatedButton(
onPressed: () async {
final url = switch (state.trackingType) {
TrackingMediumType.anime => 'https://myanimelist.net/anime/${state.data!.id}',
TrackingMediumType.manga => 'https://myanimelist.net/manga/${state.data!.id}',
final url = switch (state
.trackingType) {
TrackingMediumType.anime =>
'https://myanimelist.net/anime/${state.data!.id}',
TrackingMediumType.manga =>
'https://myanimelist.net/manga/${state.data!.id}',
};
await launchUrl(
Uri.parse(url),
mode: LaunchMode.externalApplication,
mode: LaunchMode
.externalApplication,
);
},
child: Text(t.details.mal),

View File

@@ -11,11 +11,11 @@ class SettingsPage extends StatelessWidget {
const SettingsPage({super.key});
static MaterialPageRoute<dynamic> get route => MaterialPageRoute<dynamic>(
builder: (_) => const SettingsPage(),
settings: const RouteSettings(
name: settingsRoute,
),
);
builder: (_) => const SettingsPage(),
settings: const RouteSettings(
name: settingsRoute,
),
);
@override
Widget build(BuildContext context) {
@@ -58,11 +58,11 @@ class SettingsPage extends StatelessWidget {
}
GetIt.I.get<SettingsBloc>().add(
AnimeListImportedEvent(
result.files.first.path!,
ImportListType.mal,
),
);
AnimeListImportedEvent(
result.files.first.path!,
ImportListType.mal,
),
);
},
),
ListTile(
@@ -85,30 +85,31 @@ class SettingsPage extends StatelessWidget {
}
GetIt.I.get<SettingsBloc>().add(
MangaListImportedEvent(
result.files.first.path!,
ImportListType.mal,
),
);
MangaListImportedEvent(
result.files.first.path!,
ImportListType.mal,
),
);
},
),
ListTile(
title: Text(t.settings.exportData),
onTap: () async {
// Pick the file
final result =
await FilePicker.platform.getDirectoryPath();
final result = await FilePicker.platform
.getDirectoryPath();
if (result == null) return;
if (!(await Permission.manageExternalStorage
.request())
.isGranted) return;
.isGranted)
return;
GetIt.I.get<SettingsBloc>().add(
DataExportedEvent(
result,
),
);
DataExportedEvent(
result,
),
);
},
),
ListTile(
@@ -123,18 +124,19 @@ class SettingsPage extends StatelessWidget {
context: context,
builder: (_) => AlertDialog(
title: Text(t.settings.importInvalidData.title),
content:
Text(t.settings.importInvalidData.content),
content: Text(
t.settings.importInvalidData.content,
),
),
);
return;
}
GetIt.I.get<SettingsBloc>().add(
DataImportedEvent(
result.files.first.path!,
),
);
DataImportedEvent(
result.files.first.path!,
),
);
},
),
],

View File

@@ -39,8 +39,9 @@ class DropdownSelectorState<T> extends State<DropdownSelector<T>> {
void initState() {
super.initState();
index =
widget.values.indexWhere((item) => item.value == widget.initialValue);
index = widget.values.indexWhere(
(item) => item.value == widget.initialValue,
);
}
@override
@@ -53,48 +54,49 @@ class DropdownSelectorState<T> extends State<DropdownSelector<T>> {
child: InkWell(
onTap: () async {
final result = await showModalBottomSheet<T>(
context: context,
clipBehavior: Clip.antiAlias,
builder: (context) => DraggableScrollableSheet(
initialChildSize: 1,
builder: (context, controller) => ListView.builder(
shrinkWrap: true,
controller: controller,
itemCount: widget.values.length,
itemBuilder: (context, index) => InkWell(
onTap: () {
Navigator.of(context).pop(widget.values[index].value);
},
child: Padding(
padding: const EdgeInsetsGeometry.symmetric(
horizontal: 16,
vertical: 12,
),
child: Row(
children: [
Text(
widget.values[index].text,
style: Theme.of(context).textTheme.titleLarge,
context: context,
clipBehavior: Clip.antiAlias,
builder: (context) => DraggableScrollableSheet(
initialChildSize: 1,
builder: (context, controller) => ListView.builder(
shrinkWrap: true,
controller: controller,
itemCount: widget.values.length,
itemBuilder: (context, index) => InkWell(
onTap: () {
Navigator.of(context).pop(widget.values[index].value);
},
child: Padding(
padding: const EdgeInsetsGeometry.symmetric(
horizontal: 16,
vertical: 12,
),
child: Row(
children: [
Text(
widget.values[index].text,
style: Theme.of(context).textTheme.titleLarge,
),
if (this.index == index)
const Padding(
padding: EdgeInsets.only(left: 12),
child: Icon(Icons.check),
),
if (this.index == index)
const Padding(
padding: EdgeInsets.only(left: 12),
child: Icon(Icons.check),
),
],
),
],
),
),
),
),
),
);
if (result == null) return;
if (result == widget.values[index].value) return;
setState(() {
index =
widget.values.indexWhere((item) => item.value == result);
index = widget.values.indexWhere(
(item) => item.value == result,
);
});
widget.onChanged(result);