mangayomi-mirror/lib/modules/more/statistics/statistics_provider.dart
Moustapha Kodjo Amadou 236a0cfc6d feat: add localization strings for statistics and reading time tracking #672
- Added new localization strings for total, mean per title, completion rate, watching time, reading time, average chapters per title, read percentage, and entries in multiple languages.
- Enhanced the History model to include readingTimeSeconds.
- Updated AnimeStreamController and ReaderController to track reading time and save it to history.
- Implemented reading time tracking in Anime and Novel reader views.
- Introduced statistics calculations for total reading time across histories.
- Updated statistics screen to display total reading time and average reading time per title.
2026-03-23 11:19:04 +01:00

86 lines
2.4 KiB
Dart

import 'package:isar_community/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'statistics_provider.g.dart';
class StatisticsData {
final int totalItems;
final int totalChapters;
final int readChapters;
final int completedItems;
final int downloadedItems;
final int totalReadingTimeSeconds;
const StatisticsData({
required this.totalItems,
required this.totalChapters,
required this.readChapters,
required this.completedItems,
required this.downloadedItems,
required this.totalReadingTimeSeconds,
});
}
@riverpod
Future<StatisticsData> getStatistics(
Ref ref, {
required ItemType itemType,
}) async {
final items = await isar.mangas
.filter()
.idIsNotNull()
.favoriteEqualTo(true)
.itemTypeEqualTo(itemType)
.findAll();
final chapters = await isar.chapters
.filter()
.idIsNotNull()
.manga((q) => q.favoriteEqualTo(true).itemTypeEqualTo(itemType))
.findAll();
final downloadedCount = await isar.downloads
.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++;
}
}
}
final histories = await isar.historys
.filter()
.itemTypeEqualTo(itemType)
.findAll();
int totalReadingTimeSeconds = 0;
for (final h in histories) {
totalReadingTimeSeconds += h.readingTimeSeconds ?? 0;
}
return StatisticsData(
totalItems: totalItems,
totalChapters: totalChapters,
readChapters: readChapters,
completedItems: completedItems,
downloadedItems: downloadedCount,
totalReadingTimeSeconds: totalReadingTimeSeconds,
);
}