mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-05-19 16:12:05 +00:00
Merge pull request #618 from Whiskas101/fix/statistics-synchronous-load
fix: updated statistics to use async fetch from db
This commit is contained in:
commit
0789f4c85a
2 changed files with 106 additions and 69 deletions
|
|
@ -6,37 +6,68 @@ import 'package:mangayomi/models/manga.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'statistics_provider.g.dart';
|
part 'statistics_provider.g.dart';
|
||||||
|
|
||||||
|
class StatisticsData {
|
||||||
|
final int totalItems;
|
||||||
|
final int totalChapters;
|
||||||
|
final int readChapters;
|
||||||
|
final int completedItems;
|
||||||
|
final int downloadedItems;
|
||||||
|
|
||||||
|
const StatisticsData({
|
||||||
|
required this.totalItems,
|
||||||
|
required this.totalChapters,
|
||||||
|
required this.readChapters,
|
||||||
|
required this.completedItems,
|
||||||
|
required this.downloadedItems,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
class StatisticsState extends _$StatisticsState {
|
class StatisticsState extends _$StatisticsState {
|
||||||
@override
|
@override
|
||||||
void build(ItemType itemType) {}
|
Future<StatisticsData> build(ItemType itemType) async {
|
||||||
final items = isar.mangas
|
final items = await isar.mangas
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.favoriteEqualTo(true)
|
.favoriteEqualTo(true)
|
||||||
.findAllSync();
|
.itemTypeEqualTo(itemType)
|
||||||
final chapters = isar.chapters
|
.findAll();
|
||||||
.filter()
|
|
||||||
.idIsNotNull()
|
|
||||||
.manga((q) => q.favoriteEqualTo(true))
|
|
||||||
.findAllSync();
|
|
||||||
int get totalItems => items.where((i) => i.itemType == itemType).length;
|
|
||||||
int get totalChapters =>
|
|
||||||
chapters.where((i) => i.manga.value!.itemType == itemType).length;
|
|
||||||
int get readChapters => chapters
|
|
||||||
.where((i) => i.manga.value!.itemType == itemType && (i.isRead ?? false))
|
|
||||||
.length;
|
|
||||||
int get completedItems => items
|
|
||||||
.where((i) => i.itemType == itemType && (i.status == Status.completed))
|
|
||||||
.where((e) => e.chapters.every((element) => element.isRead ?? false))
|
|
||||||
.length;
|
|
||||||
|
|
||||||
int get downloadedItems => isar.downloads
|
final chapters = await isar.chapters
|
||||||
.filter()
|
.filter()
|
||||||
.idIsNotNull()
|
.idIsNotNull()
|
||||||
.chapter((q) => q.manga((m) => m.itemTypeEqualTo(itemType)))
|
.manga((q) => q.favoriteEqualTo(true).itemTypeEqualTo(itemType))
|
||||||
.chapter((q) => q.manga((m) => m.favoriteEqualTo(true)))
|
.findAll();
|
||||||
.isDownloadEqualTo(true)
|
|
||||||
.findAllSync()
|
final downloadedCount = await isar.downloads
|
||||||
.length;
|
.filter()
|
||||||
|
.idIsNotNull()
|
||||||
|
.chapter((q) => q.manga((m) => m.itemTypeEqualTo(itemType)))
|
||||||
|
.chapter((q) => q.manga((m) => m.favoriteEqualTo(true)))
|
||||||
|
.isDownloadEqualTo(true)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
final totalItems = items.length;
|
||||||
|
final totalChapters = chapters.length;
|
||||||
|
final readChapters = chapters.where((c) => c.isRead ?? false).length;
|
||||||
|
|
||||||
|
int completedItems = 0;
|
||||||
|
for (var item in items) {
|
||||||
|
if (item.status == Status.completed) {
|
||||||
|
final itemChapters = item.chapters.toList();
|
||||||
|
if (itemChapters.isNotEmpty &&
|
||||||
|
itemChapters.every((element) => element.isRead ?? false)) {
|
||||||
|
completedItems++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StatisticsData(
|
||||||
|
totalItems: totalItems,
|
||||||
|
totalChapters: totalChapters,
|
||||||
|
readChapters: readChapters,
|
||||||
|
completedItems: completedItems,
|
||||||
|
downloadedItems: downloadedCount,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,8 @@ class _StatisticsScreenState extends ConsumerState<StatisticsScreen>
|
||||||
|
|
||||||
Widget _buildStatisticsTab({required ItemType itemType}) {
|
Widget _buildStatisticsTab({required ItemType itemType}) {
|
||||||
final l10n = context.l10n;
|
final l10n = context.l10n;
|
||||||
final stats = ref.watch(statisticsStateProvider(itemType).notifier);
|
// final stats = ref.watch(statisticsStateProvider(itemType).notifier);
|
||||||
|
final stats = ref.watch(statisticsStateProvider(itemType));
|
||||||
|
|
||||||
final title = switch (itemType) {
|
final title = switch (itemType) {
|
||||||
ItemType.manga => l10n.manga,
|
ItemType.manga => l10n.manga,
|
||||||
|
|
@ -94,47 +95,52 @@ class _StatisticsScreenState extends ConsumerState<StatisticsScreen>
|
||||||
_ => l10n.unread,
|
_ => l10n.unread,
|
||||||
};
|
};
|
||||||
|
|
||||||
final totalItems = stats.totalItems;
|
return stats.when(
|
||||||
final totalChapters = stats.totalChapters;
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
final readChapters = stats.readChapters;
|
error: (err, stack) => Center(child: Text("Err: $err")),
|
||||||
final unreadChapters = totalChapters - readChapters;
|
data: (stats) {
|
||||||
final completedItems = stats.completedItems;
|
final totalItems = stats.totalItems;
|
||||||
final downloadedItems = stats.downloadedItems;
|
final totalChapters = stats.totalChapters;
|
||||||
|
final readChapters = stats.readChapters;
|
||||||
|
final unreadChapters = totalChapters - readChapters;
|
||||||
|
final completedItems = stats.completedItems;
|
||||||
|
final downloadedItems = stats.downloadedItems;
|
||||||
|
|
||||||
final averageChapters = totalItems > 0 ? totalChapters / totalItems : 0;
|
final averageChapters = totalItems > 0 ? totalChapters / totalItems : 0;
|
||||||
final readPercentage = totalChapters > 0
|
final readPercentage = totalChapters > 0
|
||||||
? (readChapters / totalChapters) * 100
|
? (readChapters / totalChapters) * 100
|
||||||
: 0;
|
: 0;
|
||||||
final completedPercentage = totalItems > 0
|
final completedPercentage = totalItems > 0
|
||||||
? (completedItems / totalItems) * 100
|
? (completedItems / totalItems) * 100
|
||||||
: 0;
|
: 0;
|
||||||
|
return SingleChildScrollView(
|
||||||
return SingleChildScrollView(
|
padding: const EdgeInsets.all(16.0),
|
||||||
padding: const EdgeInsets.all(16.0),
|
child: Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
children: [
|
||||||
children: [
|
_buildSectionHeader('Entries'),
|
||||||
_buildSectionHeader('Entries'),
|
_buildEntriesCard(
|
||||||
_buildEntriesCard(
|
totalItems: totalItems,
|
||||||
totalItems: totalItems,
|
completedItems: completedItems,
|
||||||
completedItems: completedItems,
|
completedPercentage: completedPercentage.toDouble(),
|
||||||
completedPercentage: completedPercentage.toDouble(),
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
_buildSectionHeader(chapterLabel),
|
||||||
|
_buildChaptersCard(
|
||||||
|
totalChapters: totalChapters,
|
||||||
|
readChapters: readChapters,
|
||||||
|
unreadChapters: unreadChapters,
|
||||||
|
downloadedItems: downloadedItems,
|
||||||
|
averageChapters: averageChapters.toDouble(),
|
||||||
|
readPercentage: readPercentage.toDouble(),
|
||||||
|
title: title,
|
||||||
|
context: context,
|
||||||
|
unreadLabel: unreadLabel,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
);
|
||||||
_buildSectionHeader(chapterLabel),
|
},
|
||||||
_buildChaptersCard(
|
|
||||||
totalChapters: totalChapters,
|
|
||||||
readChapters: readChapters,
|
|
||||||
unreadChapters: unreadChapters,
|
|
||||||
downloadedItems: downloadedItems,
|
|
||||||
averageChapters: averageChapters.toDouble(),
|
|
||||||
readPercentage: readPercentage.toDouble(),
|
|
||||||
title: title,
|
|
||||||
context: context,
|
|
||||||
unreadLabel: unreadLabel,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue