mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +00:00
Added Lastest button in the sources list, organized the automatic tracking feature
This commit is contained in:
parent
da5c350be8
commit
7382ef0d96
7 changed files with 104 additions and 58 deletions
|
|
@ -1,21 +1,25 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/supports_latest.dart';
|
||||
import 'package:mangayomi/sources/source_test.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
|
||||
class SourceListTile extends StatelessWidget {
|
||||
class SourceListTile extends ConsumerWidget {
|
||||
final bool isManga;
|
||||
final Source source;
|
||||
const SourceListTile(
|
||||
{super.key, required this.source, required this.isManga});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final supportsLatest = ref.watch(supportsLatestProvider(source: source));
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
if (useTestSourceCode) {
|
||||
|
|
@ -34,7 +38,7 @@ class SourceListTile extends StatelessWidget {
|
|||
}
|
||||
});
|
||||
|
||||
context.push('/mangaHome', extra: source);
|
||||
context.push('/mangaHome', extra: (source, false));
|
||||
},
|
||||
leading: Container(
|
||||
height: 37,
|
||||
|
|
@ -96,15 +100,32 @@ class SourceListTile extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
title: Text(source.name!),
|
||||
trailing: IconButton(
|
||||
onPressed: () {
|
||||
isar.writeTxnSync(() =>
|
||||
isar.sources.putSync(source..isPinned = !source.isPinned!));
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.push_pin_outlined,
|
||||
color: source.isPinned! ? primaryColor(context) : null,
|
||||
)),
|
||||
trailing: SizedBox(
|
||||
width: 150,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (supportsLatest)
|
||||
TextButton(
|
||||
style: const ButtonStyle(
|
||||
padding: MaterialStatePropertyAll(EdgeInsets.all(10))),
|
||||
onPressed: () =>
|
||||
context.push('/mangaHome', extra: (source, true)),
|
||||
child: Text(context.l10n.latest)),
|
||||
const SizedBox(width: 10),
|
||||
IconButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
onPressed: () {
|
||||
isar.writeTxnSync(() => isar.sources
|
||||
.putSync(source..isPinned = !source.isPinned!));
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.push_pin_outlined,
|
||||
color: source.isPinned! ? primaryColor(context) : null,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1130,34 +1130,36 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
for (var manga in mangasList) {
|
||||
if (manga.isLocalArchive ?? false) {
|
||||
for (var chapter in manga.chapters) {
|
||||
final storageProvider =
|
||||
StorageProvider();
|
||||
final mangaDir = await storageProvider
|
||||
.getMangaMainDirectory(chapter);
|
||||
final path = await storageProvider
|
||||
.getMangaChapterDirectory(
|
||||
chapter,
|
||||
);
|
||||
|
||||
try {
|
||||
if (await File(
|
||||
"${mangaDir!.path}${chapter.name}.cbz")
|
||||
.exists()) {
|
||||
File("${mangaDir.path}${chapter.name}.cbz")
|
||||
.deleteSync();
|
||||
}
|
||||
path!.deleteSync(recursive: true);
|
||||
final storageProvider =
|
||||
StorageProvider();
|
||||
final mangaDir = await storageProvider
|
||||
.getMangaMainDirectory(chapter);
|
||||
final path = await storageProvider
|
||||
.getMangaChapterDirectory(
|
||||
chapter,
|
||||
);
|
||||
|
||||
try {
|
||||
if (await File(
|
||||
"${mangaDir!.path}${chapter.name}.cbz")
|
||||
.exists()) {
|
||||
File("${mangaDir.path}${chapter.name}.cbz")
|
||||
.deleteSync();
|
||||
}
|
||||
path!.deleteSync(recursive: true);
|
||||
} catch (_) {}
|
||||
isar.writeTxnSync(() {
|
||||
final download = isar.downloads
|
||||
.filter()
|
||||
.chapterIdEqualTo(chapter.id!)
|
||||
.findAllSync();
|
||||
if (download.isNotEmpty) {
|
||||
isar.downloads.deleteSync(
|
||||
download.first.id!);
|
||||
}
|
||||
});
|
||||
} catch (_) {}
|
||||
isar.writeTxnSync(() {
|
||||
final download = isar.downloads
|
||||
.filter()
|
||||
.chapterIdEqualTo(chapter.id!)
|
||||
.findAllSync();
|
||||
if (download.isNotEmpty) {
|
||||
isar.downloads
|
||||
.deleteSync(download.first.id!);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'library_state_provider.g.dart';
|
||||
|
|
@ -620,17 +621,21 @@ class MangasSetIsReadState extends _$MangasSetIsReadState {
|
|||
@override
|
||||
void build({required List<int> mangaIds}) {}
|
||||
|
||||
set() {
|
||||
void set() {
|
||||
for (var mangaid in mangaIds) {
|
||||
final manga = isar.mangas.getSync(mangaid)!;
|
||||
final chapters = manga.chapters;
|
||||
isar.writeTxnSync(() {
|
||||
for (var chapter in chapters) {
|
||||
chapter.isRead = true;
|
||||
isar.chapters.putSync(chapter..manga.value = manga);
|
||||
chapter.manga.saveSync();
|
||||
}
|
||||
});
|
||||
if (chapters.isNotEmpty) {
|
||||
chapters.last.updateTrackChapterRead(ref);
|
||||
isar.writeTxnSync(() {
|
||||
for (var chapter in chapters) {
|
||||
chapter.isRead = true;
|
||||
chapter.lastPageRead = "1";
|
||||
isar.chapters.putSync(chapter..manga.value = manga);
|
||||
chapter.manga.saveSync();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ref.read(isLongPressedMangaStateProvider.notifier).update(false);
|
||||
|
|
@ -643,7 +648,7 @@ class MangasSetUnReadState extends _$MangasSetUnReadState {
|
|||
@override
|
||||
void build({required List<int> mangaIds}) {}
|
||||
|
||||
set() {
|
||||
void set() {
|
||||
for (var mangaid in mangaIds) {
|
||||
final manga = isar.mangas.getSync(mangaid)!;
|
||||
final chapters = manga.chapters;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import 'package:mangayomi/modules/library/providers/local_archive.dart';
|
|||
import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/tracker_search_widget.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/tracker_widget.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
|
|
@ -624,6 +625,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
isar.chapters.putSync(
|
||||
chapter..manga.value = widget.manga);
|
||||
chapter.manga.saveSync();
|
||||
if (chapter.isRead!) {
|
||||
chapter.updateTrackChapterRead(ref);
|
||||
}
|
||||
}
|
||||
});
|
||||
ref
|
||||
|
|
@ -655,14 +659,18 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
),
|
||||
onPressed: () {
|
||||
int index = chapters.indexOf(chap.first);
|
||||
chapters[index + 1].updateTrackChapterRead(ref);
|
||||
isar.writeTxnSync(() {
|
||||
for (var i = index + 1;
|
||||
i < chapters.length;
|
||||
i++) {
|
||||
chapters[i].isRead = true;
|
||||
isar.chapters.putSync(chapters[i]
|
||||
..manga.value = widget.manga);
|
||||
chapters[i].manga.saveSync();
|
||||
if (!chapters[i].isRead!) {
|
||||
chapters[i].isRead = true;
|
||||
chapters[i].lastPageRead = "1";
|
||||
isar.chapters.putSync(chapters[i]
|
||||
..manga.value = widget.manga);
|
||||
chapters[i].manga.saveSync();
|
||||
}
|
||||
}
|
||||
ref
|
||||
.read(isLongPressedStateProvider.notifier)
|
||||
|
|
|
|||
|
|
@ -23,11 +23,13 @@ import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
|
|||
class MangaHomeScreen extends ConsumerStatefulWidget {
|
||||
final Source source;
|
||||
final bool isSearch;
|
||||
final bool isLatest;
|
||||
final String query;
|
||||
const MangaHomeScreen(
|
||||
{required this.source,
|
||||
this.query = "",
|
||||
this.isSearch = false,
|
||||
this.isLatest = false,
|
||||
super.key});
|
||||
|
||||
@override
|
||||
|
|
@ -48,7 +50,11 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
final ScrollController _scrollController = ScrollController();
|
||||
int _fullDataLength = 50;
|
||||
int _page = 1;
|
||||
late int _selectedIndex = widget.isSearch ? 2 : 0;
|
||||
late int _selectedIndex = widget.isLatest
|
||||
? 1
|
||||
: widget.isSearch
|
||||
? 2
|
||||
: 0;
|
||||
List<dynamic> filters = [];
|
||||
final List<MManga> _mangaList = [];
|
||||
List<TypeMangaSelector> _types(BuildContext context) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
|
|
@ -321,7 +322,7 @@ class ReaderController extends _$ReaderController {
|
|||
}
|
||||
chapterPageIndexs.add(ChapterPageIndex()
|
||||
..chapterId = chapter.id
|
||||
..index = newIndex);
|
||||
..index = isRead ? 0 : newIndex);
|
||||
final chap = chapter;
|
||||
isar.writeTxnSync(() {
|
||||
isar.settings.putSync(
|
||||
|
|
@ -350,7 +351,8 @@ class ReaderController extends _$ReaderController {
|
|||
}
|
||||
|
||||
extension ChapterExtensions on Chapter {
|
||||
void updateTrackChapterRead(AutoDisposeNotifierProviderRef ref) {
|
||||
void updateTrackChapterRead(dynamic ref) {
|
||||
if (!(ref is WidgetRef || ref is AutoDisposeNotifierProviderRef)) return;
|
||||
final updateProgressAfterReading =
|
||||
ref.watch(updateProgressAfterReadingStateProvider);
|
||||
if (!updateProgressAfterReading) return;
|
||||
|
|
|
|||
|
|
@ -143,17 +143,19 @@ class RouterNotifier extends ChangeNotifier {
|
|||
path: "/mangaHome",
|
||||
name: "mangaHome",
|
||||
builder: (context, state) {
|
||||
final source = state.extra as Source?;
|
||||
final source = state.extra as (Source?, bool);
|
||||
return MangaHomeScreen(
|
||||
source: source!,
|
||||
source: source.$1!,
|
||||
isLatest: source.$2,
|
||||
);
|
||||
},
|
||||
pageBuilder: (context, state) {
|
||||
final source = state.extra as Source?;
|
||||
final source = state.extra as (Source?, bool);
|
||||
return transitionPage(
|
||||
key: state.pageKey,
|
||||
child: MangaHomeScreen(
|
||||
source: source!,
|
||||
source: source.$1!,
|
||||
isLatest: source.$2,
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
|
|
|||
Loading…
Reference in a new issue