mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-20 10:52:05 +00:00
Merge pull request #491 from NBA2K1/main
Refactor: Consolidate _openCategory() Methods into Unified Dialog
This commit is contained in:
commit
e635e495b8
4 changed files with 222 additions and 428 deletions
|
|
@ -6,11 +6,9 @@ import 'package:bot_toast/bot_toast.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/category.dart';
|
||||
import 'package:mangayomi/models/changed.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/download.dart';
|
||||
|
|
@ -24,6 +22,7 @@ import 'package:mangayomi/modules/manga/detail/providers/update_manga_detail_pro
|
|||
import 'package:mangayomi/modules/more/categories/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
|
||||
import 'package:mangayomi/modules/widgets/category_selection_dialog.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
|
||||
import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
|
|
@ -34,13 +33,11 @@ import 'package:mangayomi/modules/library/providers/library_state_provider.dart'
|
|||
import 'package:mangayomi/modules/library/widgets/search_text_form_field.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/library_gridview_widget.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/library_listview_widget.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/list_tile_manga_category.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/chapter_sort_list_tile_widget.dart';
|
||||
import 'package:mangayomi/modules/widgets/error_text.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/utils/global_style.dart';
|
||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||
|
||||
class LibraryScreen extends ConsumerStatefulWidget {
|
||||
final ItemType itemType;
|
||||
|
|
@ -578,7 +575,18 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
onPressed: () {
|
||||
_openCategory();
|
||||
final mangaIdsList = ref.watch(
|
||||
mangasListStateProvider,
|
||||
);
|
||||
final List<Manga> bulkMangas = mangaIdsList
|
||||
.map((id) => isar.mangas.getSync(id)!)
|
||||
.toList();
|
||||
showCategorySelectionDialog(
|
||||
context: context,
|
||||
ref: ref,
|
||||
itemType: widget.itemType,
|
||||
bulkMangas: bulkMangas,
|
||||
);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.label_outline_rounded,
|
||||
|
|
@ -1073,192 +1081,6 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
return mangas;
|
||||
}
|
||||
|
||||
void _openCategory() {
|
||||
List<int> categoryIds = [];
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final mangaIdsList = ref.watch(mangasListStateProvider);
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
final List<Manga> mangasList = [];
|
||||
for (var id in mangaIdsList) {
|
||||
mangasList.add(isar.mangas.getSync(id)!);
|
||||
}
|
||||
return StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return StreamBuilder(
|
||||
stream: isar.categorys
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.forItemTypeEqualTo(widget.itemType)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
return AlertDialog(
|
||||
title: Text(l10n.set_categories),
|
||||
content: SizedBox(
|
||||
width: context.width(0.8),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||
final data = snapshot.data!;
|
||||
data.sort(
|
||||
(a, b) => (a.pos ?? 0).compareTo(b.pos ?? 0),
|
||||
);
|
||||
|
||||
final entries = data
|
||||
.where((e) => !(e.hide ?? false))
|
||||
.toList();
|
||||
if (entries.isEmpty) {
|
||||
return Text(l10n.library_no_category_exist);
|
||||
}
|
||||
return SuperListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: entries.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTileMangaCategory(
|
||||
category: entries[index],
|
||||
categoryIds: categoryIds,
|
||||
mangasList: mangasList,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
if (categoryIds.contains(
|
||||
entries[index].id,
|
||||
)) {
|
||||
categoryIds.remove(entries[index].id);
|
||||
} else {
|
||||
categoryIds.add(entries[index].id!);
|
||||
}
|
||||
});
|
||||
},
|
||||
res: (res) {
|
||||
if (res.isNotEmpty) {
|
||||
categoryIds.add(entries[index].id!);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
return Text(l10n.library_no_category_exist);
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
snapshot.hasData && snapshot.data!.isNotEmpty
|
||||
? Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.push(
|
||||
"/categories",
|
||||
extra: (
|
||||
true,
|
||||
widget.itemType == ItemType.manga
|
||||
? 0
|
||||
: widget.itemType ==
|
||||
ItemType.anime
|
||||
? 1
|
||||
: 2,
|
||||
),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.edit),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
isar.writeTxnSync(() {
|
||||
for (var id in mangaIdsList) {
|
||||
Manga? manga = isar.mangas
|
||||
.getSync(id);
|
||||
manga!.categories = categoryIds;
|
||||
isar.mangas.putSync(manga);
|
||||
ref
|
||||
.read(
|
||||
synchingProvider(
|
||||
syncId: 1,
|
||||
).notifier,
|
||||
)
|
||||
.addChangedPart(
|
||||
ActionType.updateItem,
|
||||
manga.id,
|
||||
manga.toJson(),
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
ref
|
||||
.read(
|
||||
mangasListStateProvider
|
||||
.notifier,
|
||||
)
|
||||
.clear();
|
||||
ref
|
||||
.read(
|
||||
isLongPressedMangaStateProvider
|
||||
.notifier,
|
||||
)
|
||||
.update(false);
|
||||
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.push(
|
||||
"/categories",
|
||||
extra: (
|
||||
true,
|
||||
widget.itemType == ItemType.manga
|
||||
? 0
|
||||
: widget.itemType ==
|
||||
ItemType.anime
|
||||
? 1
|
||||
: 2,
|
||||
),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.edit_categories),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _deleteManga() {
|
||||
List<int> fromLibList = [];
|
||||
List<int> downloadedChapsList = [];
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provi
|
|||
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
|
||||
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
|
||||
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart';
|
||||
import 'package:mangayomi/modules/widgets/category_selection_dialog.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
|
||||
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
|
|
@ -637,7 +638,12 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
widget.checkForUpdate(true);
|
||||
break;
|
||||
case 1:
|
||||
_openCategory(widget.manga!);
|
||||
showCategorySelectionDialog(
|
||||
context: context,
|
||||
ref: ref,
|
||||
itemType: widget.manga!.itemType,
|
||||
singleManga: widget.manga!,
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
final source = getSource(
|
||||
|
|
@ -1133,110 +1139,6 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
);
|
||||
}
|
||||
|
||||
void _openCategory(Manga manga) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
List<int> categoryIds = List<int>.from(manga.categories ?? []);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => StatefulBuilder(
|
||||
builder: (context, setState) => AlertDialog(
|
||||
title: Text(l10n.set_categories),
|
||||
content: SizedBox(
|
||||
width: context.width(0.8),
|
||||
child: StreamBuilder(
|
||||
stream: isar.categorys
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.forItemTypeEqualTo(manga.itemType)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||
return Container();
|
||||
}
|
||||
final entries = snapshot.data!;
|
||||
return SuperListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: entries.length,
|
||||
itemBuilder: (context, index) {
|
||||
final category = entries[index];
|
||||
final selected = categoryIds.contains(category.id);
|
||||
return ListTileChapterFilter(
|
||||
label: category.name!,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selected
|
||||
? categoryIds.remove(category.id)
|
||||
: categoryIds.add(category.id!);
|
||||
});
|
||||
},
|
||||
type: selected ? 1 : 0,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.push(
|
||||
"/categories",
|
||||
extra: (
|
||||
true,
|
||||
manga.itemType == ItemType.manga
|
||||
? 0
|
||||
: manga.itemType == ItemType.anime
|
||||
? 1
|
||||
: 2,
|
||||
),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.edit),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
isar.writeTxnSync(() {
|
||||
manga.favorite = true;
|
||||
manga.categories = categoryIds;
|
||||
manga.dateAdded =
|
||||
DateTime.now().millisecondsSinceEpoch;
|
||||
isar.mangas.putSync(manga);
|
||||
final sync = ref.read(
|
||||
synchingProvider(syncId: 1).notifier,
|
||||
);
|
||||
sync.addChangedPart(
|
||||
ActionType.updateItem,
|
||||
manga.id,
|
||||
manga.toJson(),
|
||||
false,
|
||||
);
|
||||
});
|
||||
if (mounted) Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showDraggableMenu() {
|
||||
final scanlators = ref.watch(scanlatorsFilterStateProvider(widget.manga!));
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
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/category.dart';
|
||||
|
|
@ -10,15 +9,14 @@ import 'package:mangayomi/models/history.dart';
|
|||
import 'package:mangayomi/modules/manga/detail/widgets/custom_floating_action_btn.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
|
||||
import 'package:mangayomi/modules/widgets/category_selection_dialog.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/manga_detail_view.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/providers/state_providers.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
|
||||
import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart';
|
||||
import 'package:mangayomi/utils/extensions/chapter.dart';
|
||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||
|
||||
class MangaDetailsView extends ConsumerStatefulWidget {
|
||||
final Manga manga;
|
||||
|
|
@ -237,36 +235,40 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
|||
elevation: 0,
|
||||
),
|
||||
onPressed: () {
|
||||
final model = widget.manga;
|
||||
final checkCategoryList = isar.categorys
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.forItemTypeEqualTo(widget.manga.itemType)
|
||||
.forItemTypeEqualTo(model.itemType)
|
||||
.isNotEmptySync();
|
||||
if (checkCategoryList) {
|
||||
_openCategory(widget.manga);
|
||||
showCategorySelectionDialog(
|
||||
context: context,
|
||||
ref: ref,
|
||||
itemType: model.itemType,
|
||||
singleManga: model,
|
||||
);
|
||||
} else {
|
||||
final model = widget.manga;
|
||||
isar.writeTxnSync(() {
|
||||
model.favorite = true;
|
||||
model.dateAdded = DateTime.now().millisecondsSinceEpoch;
|
||||
isar.mangas.putSync(model);
|
||||
ref
|
||||
.read(synchingProvider(syncId: 1).notifier)
|
||||
.addChangedPart(
|
||||
ActionType.addItem,
|
||||
null,
|
||||
model.toJson(),
|
||||
false,
|
||||
);
|
||||
ref
|
||||
.read(synchingProvider(syncId: 1).notifier)
|
||||
.addChangedPart(
|
||||
ActionType.updateItem,
|
||||
model.id,
|
||||
model.toJson(),
|
||||
false,
|
||||
);
|
||||
final sync = ref.read(
|
||||
synchingProvider(syncId: 1).notifier,
|
||||
);
|
||||
sync.addChangedPart(
|
||||
ActionType.addItem,
|
||||
null,
|
||||
model.toJson(),
|
||||
false,
|
||||
);
|
||||
sync.addChangedPart(
|
||||
ActionType.updateItem,
|
||||
model.id,
|
||||
model.toJson(),
|
||||
false,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -299,114 +301,4 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
_openCategory(Manga manga) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
List<int> categoryIds = [];
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => StatefulBuilder(
|
||||
builder: (context, setState) => AlertDialog(
|
||||
title: Text(l10n.set_categories),
|
||||
content: SizedBox(
|
||||
width: context.width(0.8),
|
||||
child: StreamBuilder(
|
||||
stream: isar.categorys
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.forItemTypeEqualTo(manga.itemType)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||
return Container();
|
||||
}
|
||||
final entries = snapshot.data!;
|
||||
return SuperListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: entries.length,
|
||||
itemBuilder: (context, index) {
|
||||
final category = entries[index];
|
||||
final selected = categoryIds.contains(category.id);
|
||||
return ListTileChapterFilter(
|
||||
label: category.name!,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selected
|
||||
? categoryIds.remove(category.id)
|
||||
: categoryIds.add(category.id!);
|
||||
});
|
||||
},
|
||||
type: selected ? 1 : 0,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
context.push(
|
||||
"/categories",
|
||||
extra: (
|
||||
true,
|
||||
manga.itemType == ItemType.manga
|
||||
? 0
|
||||
: manga.itemType == ItemType.anime
|
||||
? 1
|
||||
: 2,
|
||||
),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.edit),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(l10n.cancel),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
isar.writeTxnSync(() {
|
||||
manga.favorite = true;
|
||||
manga.categories = categoryIds;
|
||||
manga.dateAdded =
|
||||
DateTime.now().millisecondsSinceEpoch;
|
||||
isar.mangas.putSync(manga);
|
||||
final sync = ref.read(
|
||||
synchingProvider(syncId: 1).notifier,
|
||||
);
|
||||
sync.addChangedPart(
|
||||
ActionType.addItem,
|
||||
manga.id,
|
||||
manga.toJson(),
|
||||
false,
|
||||
);
|
||||
sync.addChangedPart(
|
||||
ActionType.updateItem,
|
||||
manga.id,
|
||||
manga.toJson(),
|
||||
false,
|
||||
);
|
||||
});
|
||||
if (mounted) Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.ok),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
178
lib/modules/widgets/category_selection_dialog.dart
Normal file
178
lib/modules/widgets/category_selection_dialog.dart
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
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/category.dart';
|
||||
import 'package:mangayomi/models/changed.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/list_tile_manga_category.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
|
||||
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||
|
||||
void showCategorySelectionDialog({
|
||||
required BuildContext context,
|
||||
required WidgetRef ref,
|
||||
required ItemType itemType,
|
||||
Manga? singleManga,
|
||||
List<Manga>? bulkMangas,
|
||||
}) {
|
||||
assert(
|
||||
(singleManga != null) ^ (bulkMangas != null),
|
||||
"Provide either singleManga or bulkMangas, not both.",
|
||||
);
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
final bool isBulk = bulkMangas != null;
|
||||
final bool isFavorite = !isBulk && (singleManga!.favorite ?? false);
|
||||
List<int> categoryIds = [];
|
||||
if (!isBulk && isFavorite) {
|
||||
categoryIds = List<int>.from(singleManga.categories ?? []);
|
||||
}
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => StatefulBuilder(
|
||||
builder: (context, setState) => AlertDialog(
|
||||
title: Text(l10n.set_categories),
|
||||
content: SizedBox(
|
||||
width: context.width(0.8),
|
||||
child: StreamBuilder(
|
||||
stream: isar.categorys
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.forItemTypeEqualTo(itemType)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||
return Text(l10n.library_no_category_exist);
|
||||
}
|
||||
var entries = (snapshot.data!
|
||||
..sort((a, b) => (a.pos ?? 0).compareTo(b.pos ?? 0)));
|
||||
if (isFavorite || isBulk) {
|
||||
// When item is in library, hide hidden categories in list
|
||||
entries = entries.where((e) => !(e.hide ?? false)).toList();
|
||||
}
|
||||
if (entries.isEmpty) return Text(l10n.library_no_category_exist);
|
||||
return SuperListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: entries.length,
|
||||
itemBuilder: (context, index) {
|
||||
final category = entries[index];
|
||||
final isSelected = categoryIds.contains(category.id);
|
||||
if (!isBulk) {
|
||||
return ListTileChapterFilter(
|
||||
label: category.name!,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isSelected
|
||||
? categoryIds.remove(category.id)
|
||||
: categoryIds.add(category.id!);
|
||||
});
|
||||
},
|
||||
type: isSelected ? 1 : 0,
|
||||
);
|
||||
}
|
||||
return ListTileMangaCategory(
|
||||
category: category,
|
||||
categoryIds: categoryIds,
|
||||
mangasList: bulkMangas,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
if (isSelected) {
|
||||
categoryIds.remove(category.id);
|
||||
} else {
|
||||
categoryIds.add(category.id!);
|
||||
}
|
||||
});
|
||||
},
|
||||
res: (res) {
|
||||
if (res.isNotEmpty && !isSelected) {
|
||||
categoryIds.add(category.id!);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
child: Text(l10n.edit),
|
||||
onPressed: () {
|
||||
context.push(
|
||||
"/categories",
|
||||
extra: (
|
||||
true,
|
||||
itemType == ItemType.manga
|
||||
? 0
|
||||
: itemType == ItemType.anime
|
||||
? 1
|
||||
: 2,
|
||||
),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
TextButton(
|
||||
child: Text(l10n.cancel),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
const SizedBox(width: 15),
|
||||
TextButton(
|
||||
child: Text(l10n.ok),
|
||||
onPressed: () {
|
||||
isar.writeTxnSync(() {
|
||||
if (isBulk) {
|
||||
for (var manga in bulkMangas) {
|
||||
manga.categories = categoryIds;
|
||||
isar.mangas.putSync(manga);
|
||||
_syncManga(manga, isFavorite, ref);
|
||||
}
|
||||
} else {
|
||||
if (!isFavorite) {
|
||||
singleManga!.favorite = true;
|
||||
singleManga.dateAdded =
|
||||
DateTime.now().millisecondsSinceEpoch;
|
||||
}
|
||||
singleManga.categories = categoryIds;
|
||||
isar.mangas.putSync(singleManga);
|
||||
_syncManga(singleManga, isFavorite, ref);
|
||||
}
|
||||
if (isBulk) {
|
||||
ref.read(mangasListStateProvider.notifier).clear();
|
||||
ref
|
||||
.read(isLongPressedMangaStateProvider.notifier)
|
||||
.update(false);
|
||||
}
|
||||
});
|
||||
if (context.mounted) Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _syncManga(Manga manga, bool isFavorite, WidgetRef ref) {
|
||||
final sync = ref.read(synchingProvider(syncId: 1).notifier);
|
||||
if (isFavorite) {
|
||||
sync.addChangedPart(ActionType.updateItem, manga.id, manga.toJson(), false);
|
||||
} else {
|
||||
sync.addChangedPart(ActionType.addItem, manga.id, manga.toJson(), false);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue