Add selection in history page and refresh home page after history changed (#199)

This commit is contained in:
buste
2025-02-18 11:30:30 +08:00
committed by GitHub
parent 7994ffb6a4
commit c28f4d40c2
2 changed files with 193 additions and 71 deletions

View File

@@ -33,82 +33,202 @@ class _HistoryPageState extends State<HistoryPage> {
} }
var comics = HistoryManager().getAll(); var comics = HistoryManager().getAll();
var controller = FlyoutController(); var controller = FlyoutController();
bool multiSelectMode = false;
Map<History, bool> selectedComics = {};
void selectAll() {
setState(() {
selectedComics = comics.asMap().map((k, v) => MapEntry(v, true));
});
}
void deSelect() {
setState(() {
selectedComics.clear();
});
}
void invertSelection() {
setState(() {
comics.asMap().forEach((k, v) {
selectedComics[v] = !selectedComics.putIfAbsent(v, () => false);
});
selectedComics.removeWhere((k, v) => !v);
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( List<Widget> selectActions = [
body: SmoothCustomScrollView( IconButton(
slivers: [ icon: const Icon(Icons.select_all),
SliverAppbar( tooltip: "Select All".tl,
title: Text('History'.tl), onPressed: selectAll
actions: [ ),
Tooltip( IconButton(
message: 'Clear History'.tl, icon: const Icon(Icons.deselect),
child: Flyout( tooltip: "Deselect".tl,
controller: controller, onPressed: deSelect
flyoutBuilder: (context) { ),
return FlyoutContent( IconButton(
title: 'Clear History'.tl, icon: const Icon(Icons.flip),
content: Text( tooltip: "Invert Selection".tl,
'Are you sure you want to clear your history?'.tl), onPressed: invertSelection
actions: [ ),
Button.filled( IconButton(
color: context.colorScheme.error, icon: const Icon(Icons.delete),
onPressed: () { tooltip: "Delete".tl,
HistoryManager().clearHistory(); onPressed: selectedComics.isEmpty ? null : () {
context.pop(); for (final comic in selectedComics.keys) {
}, if (comic.sourceKey.startsWith("Unknown")) {
child: Text('Clear'.tl), HistoryManager().remove(
), comic.id,
], ComicType(int.parse(comic.sourceKey.split(':')[1])),
); );
}, } else if (comic.sourceKey == 'local') {
child: IconButton( HistoryManager().remove(
icon: const Icon(Icons.clear_all), comic.id,
onPressed: () { ComicType.local,
controller.show(); );
}, } else {
), HistoryManager().remove(
), comic.id,
) ComicType(comic.sourceKey.hashCode),
], );
), }
SliverGridComics( }
comics: comics, setState(() {
badgeBuilder: (c) { multiSelectMode = false;
return ComicSource.find(c.sourceKey)?.name; selectedComics.clear();
}, });
menuBuilder: (c) { },
return [ ),
MenuEntry( ];
icon: Icons.remove,
text: 'Remove'.tl, List<Widget> normalActions = [
Tooltip(
message: 'Clear History'.tl,
child: Flyout(
controller: controller,
flyoutBuilder: (context) {
return FlyoutContent(
title: 'Clear History'.tl,
content: Text('Are you sure you want to clear your history?'.tl),
actions: [
Button.filled(
color: context.colorScheme.error, color: context.colorScheme.error,
onClick: () { onPressed: () {
if (c.sourceKey.startsWith("Unknown")) { HistoryManager().clearHistory();
HistoryManager().remove( context.pop();
c.id, },
ComicType(int.parse(c.sourceKey.split(':')[1])), child: Text('Clear'.tl),
); ),
} else if (c.sourceKey == 'local') { ],
HistoryManager().remove( );
c.id, },
ComicType.local, child: IconButton(
); icon: const Icon(Icons.clear_all),
onPressed: () {
controller.show();
},
),
),
)
];
return PopScope(
canPop: !multiSelectMode,
onPopInvokedWithResult: (didPop, result) {
if (multiSelectMode) {
setState(() {
multiSelectMode = false;
selectedComics.clear();
});
}
},
child: Scaffold(
body: SmoothCustomScrollView(
slivers: [
SliverAppbar(
leading: Tooltip(
message: multiSelectMode ? "Cancel".tl : "Back".tl,
child: IconButton(
onPressed: () {
if (multiSelectMode) {
setState(() {
multiSelectMode = false;
selectedComics.clear();
});
} else { } else {
HistoryManager().remove( context.pop();
c.id,
ComicType(c.sourceKey.hashCode),
);
} }
}, },
icon: multiSelectMode
? const Icon(Icons.close)
: const Icon(Icons.arrow_back),
), ),
]; ),
}, title: multiSelectMode
), ? Text(selectedComics.length.toString())
], : Text('History'.tl),
actions: multiSelectMode ? selectActions : normalActions,
),
SliverGridComics(
comics: comics,
selections: selectedComics,
onLongPressed: (c) {
setState(() {
multiSelectMode = true;
selectedComics[c as History] = true;
});
},
onTap: multiSelectMode ? (c) {
setState(() {
if (selectedComics.containsKey(c as History)) {
selectedComics.remove(c);
} else {
selectedComics[c] = true;
}
if (selectedComics.isEmpty) {
multiSelectMode = false;
}
});
} : null,
badgeBuilder: (c) {
return ComicSource.find(c.sourceKey)?.name;
},
menuBuilder: (c) {
return [
MenuEntry(
icon: Icons.remove,
text: 'Remove'.tl,
color: context.colorScheme.error,
onClick: () {
if (c.sourceKey.startsWith("Unknown")) {
HistoryManager().remove(
c.id,
ComicType(int.parse(c.sourceKey.split(':')[1])),
);
} else if (c.sourceKey == 'local') {
HistoryManager().remove(
c.id,
ComicType.local,
);
} else {
HistoryManager().remove(
c.id,
ComicType(c.sourceKey.hashCode),
);
}
},
),
];
},
),
],
),
), ),
); );
} }

View File

@@ -197,10 +197,12 @@ class _HistoryState extends State<_History> {
late int count; late int count;
void onHistoryChange() { void onHistoryChange() {
setState(() { if (mounted) {
history = HistoryManager().getRecent(); setState(() {
count = HistoryManager().count(); history = HistoryManager().getRecent();
}); count = HistoryManager().count();
});
}
} }
@override @override