improve ui

This commit is contained in:
nyne
2024-10-26 19:39:12 +08:00
parent e64b69d818
commit 96bf3688d0
12 changed files with 112 additions and 84 deletions

View File

@@ -73,8 +73,12 @@ class _AppbarState extends State<Appbar> {
@override
Widget build(BuildContext context) {
var content = SizedBox(
height: _kAppBarHeight,
var content = Container(
decoration: BoxDecoration(
color: widget.backgroundColor ??
context.colorScheme.surface.withOpacity(0.72),
),
height: _kAppBarHeight + context.padding.top,
child: Row(
children: [
const SizedBox(width: 8),
@@ -102,18 +106,13 @@ class _AppbarState extends State<Appbar> {
width: 8,
)
],
),
).paddingTop(context.padding.top);
if (widget.backgroundColor != Colors.transparent) {
return Material(
elevation: (_scrolledUnder && context.width < changePoint) ? 1 : 0,
surfaceTintColor: Theme.of(context).colorScheme.surfaceTint,
color: widget.backgroundColor ?? Theme.of(context).colorScheme.surface,
).paddingTop(context.padding.top),
);
return BlurEffect(
blur: _scrolledUnder ? 15 : 0,
child: content,
);
}
return content;
}
}
class SliverAppbar extends StatelessWidget {
@@ -192,7 +191,7 @@ class _MySliverAppBarDelegate extends SliverPersistentHeaderDelegate {
)
: const SizedBox()),
const SizedBox(
width: 24,
width: 16,
),
Expanded(
child: DefaultTextStyle(

View File

@@ -735,6 +735,12 @@ class ComicListState extends State<ComicList> {
}
Future<void> _loadPage(int page) async {
if (widget.loadPage == null && widget.loadNext == null) {
_error = "loadPage and loadNext can't be null at the same time";
Future.microtask(() {
setState(() {});
});
}
if (_loading[page] == true) {
return;
}
@@ -790,9 +796,6 @@ class ComicListState extends State<ComicList> {
@override
Widget build(BuildContext context) {
if (widget.loadPage == null && widget.loadNext == null) {
throw Exception("loadPage and loadNext can't be null at the same time");
}
if (_error != null) {
return Column(
children: [
@@ -814,19 +817,27 @@ class ComicListState extends State<ComicList> {
}
if (_data[_page] == null) {
_loadPage(_page);
return const Center(
return Column(
children: [
if (widget.errorLeading != null) widget.errorLeading!,
const Expanded(
child: Center(
child: CircularProgressIndicator(),
),
),
],
);
}
return SmoothCustomScrollView(
slivers: [
if (widget.leadingSliver != null) widget.leadingSliver!,
_buildSliverPageSelector(),
if (_maxPage != 1) _buildSliverPageSelector(),
SliverGridComics(
comics: _data[_page] ?? const [],
menuBuilder: widget.menuBuilder,
),
if (_data[_page]!.length > 6) _buildSliverPageSelector(),
if (_data[_page]!.length > 6 && _maxPage != 1)
_buildSliverPageSelector(),
if (widget.trailingSliver != null) widget.trailingSliver!,
],
);

View File

@@ -148,7 +148,7 @@ class _NaviPaneState extends State<NaviPane>
return _NaviPopScope(
action: () {
if (App.mainNavigatorKey!.currentState!.canPop()) {
App.mainNavigatorKey!.currentState!.pop();
App.mainNavigatorKey!.currentState!.maybePop();
} else {
SystemNavigator.pop();
}
@@ -627,16 +627,9 @@ class _NaviPopScope extends StatelessWidget {
? child
: PopScope(
canPop: App.isAndroid ? false : true,
// flutter <3.24.0 api
onPopInvoked: (value) {
action();
},
/*
flutter >=3.24.0 api
onPopInvokedWithResult: (value, result) {
action();
},
*/
child: child,
);
if (popGesture) {

View File

@@ -116,6 +116,7 @@ mixin _AppRouteTransitionMixin<T> on PageRoute<T> {
route.fullscreenDialog ||
route.animation!.status != AnimationStatus.completed ||
route.secondaryAnimation!.status != AnimationStatus.dismissed ||
!route.popGestureEnabled ||
route.navigator!.userGestureInProgress) {
return false;
}

View File

@@ -728,6 +728,7 @@ class ComicSourceParser {
return retryZone(func);
};
if(_checkExists("favorites.addFolder")) {
addFolder = (name) async {
try {
await JsEngine().runCode("""
@@ -739,6 +740,8 @@ class ComicSourceParser {
return Res.error(e.toString());
}
};
}
if(_checkExists("favorites.deleteFolder")) {
deleteFolder = (key) async {
try {
await JsEngine().runCode("""
@@ -751,6 +754,7 @@ class ComicSourceParser {
}
};
}
}
return FavoriteData(
key: _key!,

View File

@@ -153,6 +153,8 @@ class HistoryManager with ChangeNotifier {
Map<String, bool>? _cachedHistory;
static const _kMaxHistoryLength = 200;
Future<void> init() async {
_db = sqlite3.open("${App.dataPath}/history.db");
@@ -176,6 +178,12 @@ class HistoryManager with ChangeNotifier {
///
/// This function would be called when user start reading.
Future<void> addHistory(History newItem) async {
while(count() >= _kMaxHistoryLength) {
_db.execute("""
delete from history
where time == (select min(time) from history);
""");
}
_db.execute("""
insert or replace into history (id, title, subtitle, cover, time, type, ep, page, readEpisode, max_page)
values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
@@ -207,6 +215,7 @@ class HistoryManager with ChangeNotifier {
where id == ? and type == ?;
""", [id, type.value]);
updateCache();
notifyListeners();
}
Future<History?> find(String id, ComicType type) async {

View File

@@ -56,13 +56,16 @@ class _CategoryComicsPageState extends State<CategoryComicsPage> {
@override
Widget build(BuildContext context) {
var topPadding = context.padding.top + 56.0;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: Appbar(
title: Text(widget.category),
),
body: ComicList(
key: Key(widget.category + optionsValue.toString()),
leadingSliver: buildOptions().toSliver(),
errorLeading: SizedBox(height: topPadding),
leadingSliver: buildOptions().paddingTop(topPadding).toSliver(),
loadPage: (i) => data.load(
widget.category,
widget.param,

View File

@@ -92,6 +92,9 @@ class _ComicPageState extends LoadingState<ComicPage, ComicDetails>
@override
Future<Res<ComicDetails>> loadData() async {
var comicSource = ComicSource.find(widget.sourceKey);
if(comicSource == null) {
return const Res.error('Comic source not found');
}
isAddToLocalFav = LocalFavoritesManager().isExist(
widget.id,
ComicType(widget.sourceKey.hashCode),

View File

@@ -206,6 +206,7 @@ class _BodyState extends State<_Body> {
source.data['settings'][key] ?? item.value['default'] ?? '';
yield ListTile(
title: Text((item.value['title'] as String).ts(source.key)),
subtitle: Text(current, maxLines: 1, overflow: TextOverflow.ellipsis),
trailing: IconButton(
icon: const Icon(Icons.edit),
onPressed: () {

View File

@@ -71,11 +71,16 @@ class NetworkFavoritePage extends StatelessWidget {
}
}
class _NormalFavoritePage extends StatelessWidget {
_NormalFavoritePage(this.data);
class _NormalFavoritePage extends StatefulWidget {
const _NormalFavoritePage(this.data);
final FavoriteData data;
@override
State<_NormalFavoritePage> createState() => _NormalFavoritePageState();
}
class _NormalFavoritePageState extends State<_NormalFavoritePage> {
final comicListKey = GlobalKey<ComicListState>();
@override
@@ -95,7 +100,7 @@ class _NormalFavoritePage extends StatelessWidget {
)
: null,
),
title: Text(data.title),
title: Text(widget.data.title),
),
errorLeading: Appbar(
leading: Tooltip(
@@ -110,10 +115,10 @@ class _NormalFavoritePage extends StatelessWidget {
)
: null,
),
title: Text(data.title),
title: Text(widget.data.title),
),
loadPage: data.loadComic == null ? null : (i) => data.loadComic!(i),
loadNext: data.loadNext == null ? null : (next) => data.loadNext!(next),
loadPage: widget.data.loadComic == null ? null : (i) => widget.data.loadComic!(i),
loadNext: widget.data.loadNext == null ? null : (next) => widget.data.loadNext!(next),
menuBuilder: (comic) {
return [
MenuEntry(
@@ -280,7 +285,7 @@ class _MultiFolderFavoritesPageState extends State<_MultiFolderFavoritesPage> {
}
}),
maxCrossAxisExtent: 450,
itemHeight: 64,
itemHeight: 52,
),
if (widget.data.addFolder != null)
SliverToBoxAdapter(
@@ -342,17 +347,13 @@ class _FolderTile extends StatelessWidget {
return Material(
child: InkWell(
onTap: onTap,
borderRadius: const BorderRadius.all(Radius.circular(8)),
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 16, 8),
padding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
child: Row(
children: [
const SizedBox(
width: 16,
),
Icon(
Icons.folder,
size: 35,
size: 28,
color: Theme.of(context).colorScheme.secondary,
),
const SizedBox(
@@ -370,15 +371,11 @@ class _FolderTile extends StatelessWidget {
),
if (deleteFolder != null)
IconButton(
icon: const Icon(Icons.delete_forever_outlined),
icon: const Icon(Icons.delete_outline),
onPressed: () => onDeleteFolder(context),
)
else
const Icon(Icons.arrow_right),
if (deleteFolder == null)
const SizedBox(
width: 8,
)
],
),
),

View File

@@ -85,7 +85,7 @@ class _HistoryPageState extends State<HistoryPage> {
e.subtitle,
null,
getDescription(e),
e.type.comicSource?.key ?? "Invalid",
e.type.comicSource?.key ?? "Invalid:${e.type.value}",
null,
null,
);
@@ -100,10 +100,17 @@ class _HistoryPageState extends State<HistoryPage> {
icon: Icons.remove,
text: 'Remove'.tl,
onClick: () {
if(c.sourceKey.startsWith("Invalid")) {
HistoryManager().remove(
c.id,
ComicType(int.parse(c.sourceKey.split(':')[1])),
);
} else {
HistoryManager().remove(
c.id,
ComicType(c.sourceKey.hashCode),
);
}
},
),
];

View File

@@ -38,14 +38,17 @@ class _RankingPageState extends State<RankingPage> {
@override
Widget build(BuildContext context) {
var topPadding = context.padding.top + 56;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: Appbar(
title: Text("Ranking".tl),
),
body: Column(
children: [
Expanded(
child: ComicList(
body: ComicList(
key: Key(optionValue),
errorLeading: SizedBox(height: topPadding),
leadingSliver:
buildOptions().sliverPadding(EdgeInsets.only(top: topPadding)),
loadPage: data.rankingData!.load == null
? null
: (i) => data.rankingData!.load!(optionValue, i),
@@ -53,9 +56,6 @@ class _RankingPageState extends State<RankingPage> {
? null
: (i) => data.rankingData!.loadWithNext!(optionValue, i),
),
),
],
),
);
}