make explore pages keep alive and listen for settings change

This commit is contained in:
nyne
2024-11-02 10:00:23 +08:00
parent 2d628ec9b1
commit 2db3f5a72e
4 changed files with 109 additions and 38 deletions

View File

@@ -872,6 +872,7 @@ class ComicListState extends State<ComicList> {
try { try {
if (widget.loadPage != null) { if (widget.loadPage != null) {
var res = await widget.loadPage!(page); var res = await widget.loadPage!(page);
if(!mounted) return;
if (res.success) { if (res.success) {
if (res.data.isEmpty) { if (res.data.isEmpty) {
_data[page] = const []; _data[page] = const [];

View File

@@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:venera/foundation/app.dart'; import 'package:venera/foundation/app.dart';
import 'package:venera/utils/io.dart'; import 'package:venera/utils/io.dart';
@@ -85,7 +86,7 @@ class _Appdata {
final appdata = _Appdata(); final appdata = _Appdata();
class _Settings { class _Settings with ChangeNotifier {
_Settings(); _Settings();
final _data = <String, dynamic>{ final _data = <String, dynamic>{
@@ -117,6 +118,7 @@ class _Settings {
operator []=(String key, dynamic value) { operator []=(String key, dynamic value) {
_data[key] = value; _data[key] = value;
notifyListeners();
} }
@override @override

View File

@@ -5,6 +5,7 @@ import 'package:venera/foundation/appdata.dart';
import 'package:venera/foundation/comic_source/comic_source.dart'; import 'package:venera/foundation/comic_source/comic_source.dart';
import 'package:venera/foundation/res.dart'; import 'package:venera/foundation/res.dart';
import 'package:venera/foundation/state_controller.dart'; import 'package:venera/foundation/state_controller.dart';
import 'package:venera/utils/ext.dart';
import 'package:venera/utils/translations.dart'; import 'package:venera/utils/translations.dart';
class ExplorePage extends StatefulWidget { class ExplorePage extends StatefulWidget {
@@ -15,7 +16,7 @@ class ExplorePage extends StatefulWidget {
} }
class _ExplorePageState extends State<ExplorePage> class _ExplorePageState extends State<ExplorePage>
with TickerProviderStateMixin { with TickerProviderStateMixin, AutomaticKeepAliveClientMixin<ExplorePage> {
late TabController controller; late TabController controller;
bool showFB = true; bool showFB = true;
@@ -24,6 +25,24 @@ class _ExplorePageState extends State<ExplorePage>
late List<String> pages; late List<String> pages;
void onSettingsChanged() {
var explorePages = List<String>.from(appdata.settings["explore_pages"]);
var all = ComicSource.all()
.map((e) => e.explorePages)
.expand((e) => e.map((e) => e.title))
.toList();
explorePages = explorePages.where((e) => all.contains(e)).toList();
if(!pages.isEqualsTo(explorePages)){
setState(() {
pages = explorePages;
controller = TabController(
length: pages.length,
vsync: this,
);
});
}
}
@override @override
void initState() { void initState() {
pages = List<String>.from(appdata.settings["explore_pages"]); pages = List<String>.from(appdata.settings["explore_pages"]);
@@ -36,9 +55,17 @@ class _ExplorePageState extends State<ExplorePage>
length: pages.length, length: pages.length,
vsync: this, vsync: this,
); );
appdata.settings.addListener(onSettingsChanged);
super.initState(); super.initState();
} }
@override
void dispose() {
controller.dispose();
appdata.settings.removeListener(onSettingsChanged);
super.dispose();
}
void refresh() { void refresh() {
int page = controller.index; int page = controller.index;
String currentPageId = pages[page]; String currentPageId = pages[page];
@@ -83,12 +110,14 @@ class _ExplorePageState extends State<ExplorePage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context);
if (pages.isEmpty) { if (pages.isEmpty) {
return buildEmpty(); return buildEmpty();
} }
Widget tabBar = Material( Widget tabBar = Material(
child: FilledTabBar( child: FilledTabBar(
key: Key(pages.toString()),
tabs: pages.map((e) => buildTab(e)).toList(), tabs: pages.map((e) => buildTab(e)).toList(),
controller: controller, controller: controller,
), ),
@@ -118,7 +147,8 @@ class _ExplorePageState extends State<ExplorePage>
setState(() { setState(() {
showFB = false; showFB = false;
}); });
} else if ((current < location || current == 0) && !showFB) { } else if ((current < location || current == 0) &&
!showFB) {
setState(() { setState(() {
showFB = true; showFB = true;
}); });
@@ -138,7 +168,8 @@ class _ExplorePageState extends State<ExplorePage>
), ),
) )
], ],
)), ),
),
Positioned( Positioned(
right: 16, right: 16,
bottom: 16, bottom: 16,
@@ -159,6 +190,9 @@ class _ExplorePageState extends State<ExplorePage>
], ],
); );
} }
@override
bool get wantKeepAlive => true;
} }
class _SingleExplorePage extends StatefulWidget { class _SingleExplorePage extends StatefulWidget {
@@ -170,7 +204,8 @@ class _SingleExplorePage extends StatefulWidget {
State<_SingleExplorePage> createState() => _SingleExplorePageState(); State<_SingleExplorePage> createState() => _SingleExplorePageState();
} }
class _SingleExplorePageState extends StateWithController<_SingleExplorePage> { class _SingleExplorePageState extends StateWithController<_SingleExplorePage>
with AutomaticKeepAliveClientMixin<_SingleExplorePage> {
late final ExplorePageData data; late final ExplorePageData data;
bool loading = true; bool loading = true;
@@ -183,6 +218,16 @@ class _SingleExplorePageState extends StateWithController<_SingleExplorePage> {
int key = 0; int key = 0;
bool _wantKeepAlive = true;
void onSettingsChanged() {
var explorePages = appdata.settings["explore_pages"];
if (!explorePages.contains(widget.title)) {
_wantKeepAlive = false;
updateKeepAlive();
}
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -195,11 +240,19 @@ class _SingleExplorePageState extends StateWithController<_SingleExplorePage> {
} }
} }
} }
appdata.settings.addListener(onSettingsChanged);
throw "Explore Page ${widget.title} Not Found!"; throw "Explore Page ${widget.title} Not Found!";
} }
@override
void dispose() {
appdata.settings.removeListener(onSettingsChanged);
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context);
if (data.loadMultiPart != null) { if (data.loadMultiPart != null) {
return buildMultiPart(); return buildMultiPart();
} else if (data.loadPage != null || data.loadNext != null) { } else if (data.loadPage != null || data.loadNext != null) {
@@ -284,6 +337,9 @@ class _SingleExplorePageState extends StateWithController<_SingleExplorePage> {
}); });
} }
} }
@override
bool get wantKeepAlive => _wantKeepAlive;
} }
class _MixedExplorePage extends StatefulWidget { class _MixedExplorePage extends StatefulWidget {

View File

@@ -24,6 +24,18 @@ extension ListExt<T> on List<T>{
add(value); add(value);
} }
} }
bool isEqualsTo(List<T> list){
if(length != list.length){
return false;
}
for(int i=0; i<length; i++){
if(this[i] != list[i]){
return false;
}
}
return true;
}
} }
extension StringExt on String{ extension StringExt on String{