mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
make explore pages keep alive and listen for settings change
This commit is contained in:
@@ -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 [];
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
),
|
),
|
||||||
@@ -97,48 +126,50 @@ class _ExplorePageState extends State<ExplorePage>
|
|||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
tabBar,
|
tabBar,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NotificationListener<ScrollNotification>(
|
child: NotificationListener<ScrollNotification>(
|
||||||
onNotification: (notifications) {
|
onNotification: (notifications) {
|
||||||
if (notifications.metrics.axis == Axis.horizontal) {
|
if (notifications.metrics.axis == Axis.horizontal) {
|
||||||
if (!showFB) {
|
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(() {
|
setState(() {
|
||||||
showFB = true;
|
showFB = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var current = notifications.metrics.pixels;
|
location = current;
|
||||||
|
return false;
|
||||||
if ((current > location && current != 0) && showFB) {
|
},
|
||||||
setState(() {
|
child: MediaQuery.removePadding(
|
||||||
showFB = false;
|
context: context,
|
||||||
});
|
removeTop: true,
|
||||||
} else if ((current < location || current == 0) && !showFB) {
|
child: TabBarView(
|
||||||
setState(() {
|
controller: controller,
|
||||||
showFB = true;
|
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(
|
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 {
|
||||||
|
@@ -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{
|
||||||
|
Reference in New Issue
Block a user