diff --git a/lib/components/comic.dart b/lib/components/comic.dart index ee3a2d4..2c4c4c3 100644 --- a/lib/components/comic.dart +++ b/lib/components/comic.dart @@ -872,6 +872,7 @@ class ComicListState extends State { try { if (widget.loadPage != null) { var res = await widget.loadPage!(page); + if(!mounted) return; if (res.success) { if (res.data.isEmpty) { _data[page] = const []; diff --git a/lib/foundation/appdata.dart b/lib/foundation/appdata.dart index 7a083c9..a81f42e 100644 --- a/lib/foundation/appdata.dart +++ b/lib/foundation/appdata.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:flutter/foundation.dart'; import 'package:path_provider/path_provider.dart'; import 'package:venera/foundation/app.dart'; import 'package:venera/utils/io.dart'; @@ -85,7 +86,7 @@ class _Appdata { final appdata = _Appdata(); -class _Settings { +class _Settings with ChangeNotifier { _Settings(); final _data = { @@ -117,6 +118,7 @@ class _Settings { operator []=(String key, dynamic value) { _data[key] = value; + notifyListeners(); } @override diff --git a/lib/pages/explore_page.dart b/lib/pages/explore_page.dart index f17db5a..90230a0 100644 --- a/lib/pages/explore_page.dart +++ b/lib/pages/explore_page.dart @@ -5,6 +5,7 @@ import 'package:venera/foundation/appdata.dart'; import 'package:venera/foundation/comic_source/comic_source.dart'; import 'package:venera/foundation/res.dart'; import 'package:venera/foundation/state_controller.dart'; +import 'package:venera/utils/ext.dart'; import 'package:venera/utils/translations.dart'; class ExplorePage extends StatefulWidget { @@ -15,7 +16,7 @@ class ExplorePage extends StatefulWidget { } class _ExplorePageState extends State - with TickerProviderStateMixin { + with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { late TabController controller; bool showFB = true; @@ -24,6 +25,24 @@ class _ExplorePageState extends State late List pages; + void onSettingsChanged() { + var explorePages = List.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 void initState() { pages = List.from(appdata.settings["explore_pages"]); @@ -36,9 +55,17 @@ class _ExplorePageState extends State length: pages.length, vsync: this, ); + appdata.settings.addListener(onSettingsChanged); super.initState(); } + @override + void dispose() { + controller.dispose(); + appdata.settings.removeListener(onSettingsChanged); + super.dispose(); + } + void refresh() { int page = controller.index; String currentPageId = pages[page]; @@ -83,12 +110,14 @@ class _ExplorePageState extends State @override Widget build(BuildContext context) { + super.build(context); if (pages.isEmpty) { return buildEmpty(); } Widget tabBar = Material( child: FilledTabBar( + key: Key(pages.toString()), tabs: pages.map((e) => buildTab(e)).toList(), controller: controller, ), @@ -97,48 +126,50 @@ class _ExplorePageState extends State return Stack( children: [ Positioned.fill( - child: Column( - children: [ - tabBar, - Expanded( - child: NotificationListener( - onNotification: (notifications) { - if (notifications.metrics.axis == Axis.horizontal) { - if (!showFB) { + child: Column( + children: [ + tabBar, + Expanded( + child: NotificationListener( + onNotification: (notifications) { + if (notifications.metrics.axis == Axis.horizontal) { + if (!showFB) { + setState(() { + showFB = true; + }); + } + return true; + } + + var current = notifications.metrics.pixels; + + if ((current > location && current != 0) && showFB) { + setState(() { + showFB = false; + }); + } else if ((current < location || current == 0) && + !showFB) { setState(() { showFB = true; }); } - return true; - } - var current = notifications.metrics.pixels; - - if ((current > location && current != 0) && showFB) { - setState(() { - showFB = false; - }); - } else if ((current < location || current == 0) && !showFB) { - setState(() { - showFB = true; - }); - } - - location = current; - return false; - }, - child: MediaQuery.removePadding( - context: context, - removeTop: true, - child: TabBarView( - controller: controller, - children: pages.map((e) => buildBody(e)).toList(), + location = current; + return false; + }, + child: MediaQuery.removePadding( + context: context, + removeTop: true, + child: TabBarView( + controller: controller, + children: pages.map((e) => buildBody(e)).toList(), + ), ), ), - ), - ) - ], - )), + ) + ], + ), + ), Positioned( right: 16, bottom: 16, @@ -159,6 +190,9 @@ class _ExplorePageState extends State ], ); } + + @override + bool get wantKeepAlive => true; } class _SingleExplorePage extends StatefulWidget { @@ -170,7 +204,8 @@ class _SingleExplorePage extends StatefulWidget { State<_SingleExplorePage> createState() => _SingleExplorePageState(); } -class _SingleExplorePageState extends StateWithController<_SingleExplorePage> { +class _SingleExplorePageState extends StateWithController<_SingleExplorePage> + with AutomaticKeepAliveClientMixin<_SingleExplorePage> { late final ExplorePageData data; bool loading = true; @@ -183,6 +218,16 @@ class _SingleExplorePageState extends StateWithController<_SingleExplorePage> { int key = 0; + bool _wantKeepAlive = true; + + void onSettingsChanged() { + var explorePages = appdata.settings["explore_pages"]; + if (!explorePages.contains(widget.title)) { + _wantKeepAlive = false; + updateKeepAlive(); + } + } + @override void initState() { super.initState(); @@ -195,11 +240,19 @@ class _SingleExplorePageState extends StateWithController<_SingleExplorePage> { } } } + appdata.settings.addListener(onSettingsChanged); throw "Explore Page ${widget.title} Not Found!"; } + @override + void dispose() { + appdata.settings.removeListener(onSettingsChanged); + super.dispose(); + } + @override Widget build(BuildContext context) { + super.build(context); if (data.loadMultiPart != null) { return buildMultiPart(); } 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 { diff --git a/lib/utils/ext.dart b/lib/utils/ext.dart index ba414a2..172bab3 100644 --- a/lib/utils/ext.dart +++ b/lib/utils/ext.dart @@ -24,6 +24,18 @@ extension ListExt on List{ add(value); } } + + bool isEqualsTo(List list){ + if(length != list.length){ + return false; + } + for(int i=0; i