mirror of
https://github.com/venera-app/venera.git
synced 2025-09-27 07:47:24 +00:00
Add buttons for adding pages
This commit is contained in:
@@ -269,12 +269,19 @@ class _MySliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
||||
}
|
||||
|
||||
class AppTabBar extends StatefulWidget {
|
||||
const AppTabBar({super.key, this.controller, required this.tabs});
|
||||
const AppTabBar({
|
||||
super.key,
|
||||
this.controller,
|
||||
required this.tabs,
|
||||
this.actionButton,
|
||||
});
|
||||
|
||||
final TabController? controller;
|
||||
|
||||
final List<Tab> tabs;
|
||||
|
||||
final Widget? actionButton;
|
||||
|
||||
@override
|
||||
State<AppTabBar> createState() => _AppTabBarState();
|
||||
}
|
||||
@@ -378,7 +385,8 @@ class _AppTabBarState extends State<AppTabBar> {
|
||||
painter: painter,
|
||||
child: _TabRow(
|
||||
callback: _tabLayoutCallback,
|
||||
children: List.generate(widget.tabs.length, buildTab),
|
||||
children: List.generate(widget.tabs.length, buildTab)
|
||||
..addIfNotNull(widget.actionButton?.padding(tabPadding)),
|
||||
),
|
||||
).paddingHorizontal(4),
|
||||
);
|
||||
@@ -396,7 +404,8 @@ class _AppTabBarState extends State<AppTabBar> {
|
||||
),
|
||||
),
|
||||
),
|
||||
child: widget.tabs.isEmpty ? const SizedBox() : child);
|
||||
child: widget.tabs.isEmpty ? const SizedBox() : child,
|
||||
);
|
||||
}
|
||||
|
||||
int? previousIndex;
|
||||
@@ -633,7 +642,6 @@ class _TabViewBodyState extends State<TabViewBody> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SearchBarController {
|
||||
_SearchBarMixin? _state;
|
||||
|
||||
@@ -906,3 +914,42 @@ class _SearchBarState extends State<AppSearchBar> with _SearchBarMixin {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TabActionButton extends StatelessWidget {
|
||||
const TabActionButton({
|
||||
super.key,
|
||||
required this.icon,
|
||||
required this.text,
|
||||
required this.onPressed,
|
||||
});
|
||||
|
||||
final Icon icon;
|
||||
|
||||
final String text;
|
||||
|
||||
final void Function() onPressed;
|
||||
|
||||
static const _kTabHeight = 46.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: onPressed,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Container(
|
||||
height: _kTabHeight,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: IconTheme(
|
||||
data: IconThemeData(size: 20, color: context.colorScheme.primary),
|
||||
child: Row(
|
||||
children: [
|
||||
icon,
|
||||
const SizedBox(width: 8),
|
||||
Text(text, style: ts.withColor(context.colorScheme.primary)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -3,32 +3,68 @@ import 'package:venera/components/components.dart';
|
||||
import 'package:venera/foundation/app.dart';
|
||||
import 'package:venera/foundation/appdata.dart';
|
||||
import 'package:venera/foundation/comic_source/comic_source.dart';
|
||||
import 'package:venera/foundation/state_controller.dart';
|
||||
import 'package:venera/pages/ranking_page.dart';
|
||||
import 'package:venera/pages/search_result_page.dart';
|
||||
import 'package:venera/pages/settings/settings_page.dart';
|
||||
import 'package:venera/utils/ext.dart';
|
||||
import 'package:venera/utils/translations.dart';
|
||||
|
||||
import 'category_comics_page.dart';
|
||||
|
||||
class CategoriesPage extends StatelessWidget {
|
||||
class CategoriesPage extends StatefulWidget {
|
||||
const CategoriesPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StateBuilder<SimpleController>(
|
||||
tag: "category",
|
||||
init: SimpleController(),
|
||||
builder: (controller) {
|
||||
var categories = List.from(appdata.settings["categories"]);
|
||||
State<CategoriesPage> createState() => _CategoriesPageState();
|
||||
}
|
||||
|
||||
class _CategoriesPageState extends State<CategoriesPage> {
|
||||
var categories = <String>[];
|
||||
|
||||
void onSettingsChanged() {
|
||||
var categories =
|
||||
List.from(appdata.settings["categories"]).whereType<String>().toList();
|
||||
var allCategories = ComicSource.all()
|
||||
.map((e) => e.categoryData?.key)
|
||||
.where((element) => element != null)
|
||||
.map((e) => e!)
|
||||
.toList();
|
||||
categories = categories
|
||||
.where((element) => allCategories.contains(element))
|
||||
.toList();
|
||||
categories =
|
||||
categories.where((element) => allCategories.contains(element)).toList();
|
||||
if (!categories.isEqualsTo(this.categories)) {
|
||||
setState(() {
|
||||
this.categories = categories;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
var categories =
|
||||
List.from(appdata.settings["categories"]).whereType<String>().toList();
|
||||
var allCategories = ComicSource.all()
|
||||
.map((e) => e.categoryData?.key)
|
||||
.where((element) => element != null)
|
||||
.map((e) => e!)
|
||||
.toList();
|
||||
this.categories =
|
||||
categories.where((element) => allCategories.contains(element)).toList();
|
||||
appdata.settings.addListener(onSettingsChanged);
|
||||
}
|
||||
|
||||
void addPage() {
|
||||
showPopUpWidget(App.rootContext, setCategoryPagesWidget());
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
appdata.settings.removeListener(onSettingsChanged);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (categories.isEmpty) {
|
||||
var msg = "No Category Pages".tl;
|
||||
msg += '\n';
|
||||
@@ -40,7 +76,7 @@ class CategoriesPage extends StatelessWidget {
|
||||
return NetworkError(
|
||||
message: msg,
|
||||
retry: () {
|
||||
controller.update();
|
||||
setState(() {});
|
||||
},
|
||||
withAppbar: false,
|
||||
);
|
||||
@@ -66,18 +102,21 @@ class CategoriesPage extends StatelessWidget {
|
||||
key: Key(e),
|
||||
);
|
||||
}).toList(),
|
||||
actionButton: TabActionButton(
|
||||
icon: const Icon(Icons.add),
|
||||
text: "Add".tl,
|
||||
onPressed: addPage,
|
||||
),
|
||||
).paddingTop(context.padding.top),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
children:
|
||||
categories.map((e) => _CategoryPage(e)).toList()),
|
||||
children: categories.map((e) => _CategoryPage(e)).toList(),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ 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/pages/search_result_page.dart';
|
||||
import 'package:venera/pages/settings/settings_page.dart';
|
||||
import 'package:venera/utils/ext.dart';
|
||||
import 'package:venera/utils/translations.dart';
|
||||
|
||||
@@ -56,6 +57,10 @@ class _ExplorePageState extends State<ExplorePage>
|
||||
}
|
||||
}
|
||||
|
||||
void addPage() {
|
||||
showPopUpWidget(App.rootContext, setExplorePagesWidget());
|
||||
}
|
||||
|
||||
NaviPaneState? naviPane;
|
||||
|
||||
@override
|
||||
@@ -141,6 +146,11 @@ class _ExplorePageState extends State<ExplorePage>
|
||||
key: PageStorageKey(pages.toString()),
|
||||
tabs: pages.map((e) => buildTab(e)).toList(),
|
||||
controller: controller,
|
||||
actionButton: TabActionButton(
|
||||
icon: const Icon(Icons.add),
|
||||
text: "Add".tl,
|
||||
onPressed: addPage,
|
||||
),
|
||||
),
|
||||
).paddingTop(context.padding.top);
|
||||
|
||||
|
@@ -30,35 +30,11 @@ class _ExploreSettingsState extends State<ExploreSettings> {
|
||||
).toSliver(),
|
||||
_PopupWindowSetting(
|
||||
title: "Explore Pages".tl,
|
||||
builder: () {
|
||||
var pages = <String, String>{};
|
||||
for (var c in ComicSource.all()) {
|
||||
for (var page in c.explorePages) {
|
||||
pages[page.title] = page.title;
|
||||
}
|
||||
}
|
||||
return _MultiPagesFilter(
|
||||
title: "Explore Pages".tl,
|
||||
settingsIndex: "explore_pages",
|
||||
pages: pages,
|
||||
);
|
||||
},
|
||||
builder: setExplorePagesWidget,
|
||||
).toSliver(),
|
||||
_PopupWindowSetting(
|
||||
title: "Category Pages".tl,
|
||||
builder: () {
|
||||
var pages = <String, String>{};
|
||||
for (var c in ComicSource.all()) {
|
||||
if (c.categoryData != null) {
|
||||
pages[c.categoryData!.key] = c.categoryData!.title;
|
||||
}
|
||||
}
|
||||
return _MultiPagesFilter(
|
||||
title: "Category Pages".tl,
|
||||
settingsIndex: "categories",
|
||||
pages: pages,
|
||||
);
|
||||
},
|
||||
builder: setCategoryPagesWidget,
|
||||
).toSliver(),
|
||||
_PopupWindowSetting(
|
||||
title: "Network Favorite Pages".tl,
|
||||
@@ -205,3 +181,31 @@ class _ManageBlockingWordViewState extends State<_ManageBlockingWordView> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget setExplorePagesWidget() {
|
||||
var pages = <String, String>{};
|
||||
for (var c in ComicSource.all()) {
|
||||
for (var page in c.explorePages) {
|
||||
pages[page.title] = page.title;
|
||||
}
|
||||
}
|
||||
return _MultiPagesFilter(
|
||||
title: "Explore Pages".tl,
|
||||
settingsIndex: "explore_pages",
|
||||
pages: pages,
|
||||
);
|
||||
}
|
||||
|
||||
Widget setCategoryPagesWidget() {
|
||||
var pages = <String, String>{};
|
||||
for (var c in ComicSource.all()) {
|
||||
if (c.categoryData != null) {
|
||||
pages[c.categoryData!.key] = c.categoryData!.title;
|
||||
}
|
||||
}
|
||||
return _MultiPagesFilter(
|
||||
title: "Category Pages".tl,
|
||||
settingsIndex: "categories",
|
||||
pages: pages,
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user