From 96bf3688d09acd8ef352d93b22537507f4c6accf Mon Sep 17 00:00:00 2001 From: nyne Date: Sat, 26 Oct 2024 19:39:12 +0800 Subject: [PATCH] improve ui --- lib/components/appbar.dart | 27 ++++++------- lib/components/comic.dart | 25 ++++++++---- lib/components/navigation_bar.dart | 9 +---- lib/foundation/app_page_route.dart | 1 + lib/foundation/comic_source/parser.dart | 40 ++++++++++--------- lib/foundation/history.dart | 9 +++++ lib/pages/category_comics_page.dart | 5 ++- lib/pages/comic_page.dart | 3 ++ lib/pages/comic_source_page.dart | 1 + .../favorites/network_favorites_page.dart | 33 +++++++-------- lib/pages/history_page.dart | 17 +++++--- lib/pages/ranking_page.dart | 26 ++++++------ 12 files changed, 112 insertions(+), 84 deletions(-) diff --git a/lib/components/appbar.dart b/lib/components/appbar.dart index 91b7392..560e407 100644 --- a/lib/components/appbar.dart +++ b/lib/components/appbar.dart @@ -73,8 +73,12 @@ class _AppbarState extends State { @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,17 +106,12 @@ class _AppbarState extends State { 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, - child: content, - ); - } - return content; + ).paddingTop(context.padding.top), + ); + return BlurEffect( + blur: _scrolledUnder ? 15 : 0, + child: content, + ); } } @@ -192,7 +191,7 @@ class _MySliverAppBarDelegate extends SliverPersistentHeaderDelegate { ) : const SizedBox()), const SizedBox( - width: 24, + width: 16, ), Expanded( child: DefaultTextStyle( diff --git a/lib/components/comic.dart b/lib/components/comic.dart index c24f915..6cc1375 100644 --- a/lib/components/comic.dart +++ b/lib/components/comic.dart @@ -735,6 +735,12 @@ class ComicListState extends State { } Future _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 { @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 { } if (_data[_page] == null) { _loadPage(_page); - return const Center( - child: CircularProgressIndicator(), + 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!, ], ); diff --git a/lib/components/navigation_bar.dart b/lib/components/navigation_bar.dart index 9707776..8f99760 100644 --- a/lib/components/navigation_bar.dart +++ b/lib/components/navigation_bar.dart @@ -148,7 +148,7 @@ class _NaviPaneState extends State 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) { diff --git a/lib/foundation/app_page_route.dart b/lib/foundation/app_page_route.dart index ab4afb6..bab0f24 100644 --- a/lib/foundation/app_page_route.dart +++ b/lib/foundation/app_page_route.dart @@ -116,6 +116,7 @@ mixin _AppRouteTransitionMixin on PageRoute { route.fullscreenDialog || route.animation!.status != AnimationStatus.completed || route.secondaryAnimation!.status != AnimationStatus.dismissed || + !route.popGestureEnabled || route.navigator!.userGestureInProgress) { return false; } diff --git a/lib/foundation/comic_source/parser.dart b/lib/foundation/comic_source/parser.dart index b9f88df..ed723df 100644 --- a/lib/foundation/comic_source/parser.dart +++ b/lib/foundation/comic_source/parser.dart @@ -728,28 +728,32 @@ class ComicSourceParser { return retryZone(func); }; - addFolder = (name) async { - try { - await JsEngine().runCode(""" + if(_checkExists("favorites.addFolder")) { + addFolder = (name) async { + try { + await JsEngine().runCode(""" ComicSource.sources.$_key.favorites.addFolder(${jsonEncode(name)}) """); - return const Res(true); - } catch (e, s) { - Log.error("Network", "$e\n$s"); - return Res.error(e.toString()); - } - }; - deleteFolder = (key) async { - try { - await JsEngine().runCode(""" + return const Res(true); + } catch (e, s) { + Log.error("Network", "$e\n$s"); + return Res.error(e.toString()); + } + }; + } + if(_checkExists("favorites.deleteFolder")) { + deleteFolder = (key) async { + try { + await JsEngine().runCode(""" ComicSource.sources.$_key.favorites.deleteFolder(${jsonEncode(key)}) """); - return const Res(true); - } catch (e, s) { - Log.error("Network", "$e\n$s"); - return Res.error(e.toString()); - } - }; + return const Res(true); + } catch (e, s) { + Log.error("Network", "$e\n$s"); + return Res.error(e.toString()); + } + }; + } } return FavoriteData( diff --git a/lib/foundation/history.dart b/lib/foundation/history.dart index 47ee14a..30feb28 100644 --- a/lib/foundation/history.dart +++ b/lib/foundation/history.dart @@ -153,6 +153,8 @@ class HistoryManager with ChangeNotifier { Map? _cachedHistory; + static const _kMaxHistoryLength = 200; + Future 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 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 find(String id, ComicType type) async { diff --git a/lib/pages/category_comics_page.dart b/lib/pages/category_comics_page.dart index 3085256..33b12cf 100644 --- a/lib/pages/category_comics_page.dart +++ b/lib/pages/category_comics_page.dart @@ -56,13 +56,16 @@ class _CategoryComicsPageState extends State { @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, diff --git a/lib/pages/comic_page.dart b/lib/pages/comic_page.dart index 9383934..7176809 100644 --- a/lib/pages/comic_page.dart +++ b/lib/pages/comic_page.dart @@ -92,6 +92,9 @@ class _ComicPageState extends LoadingState @override Future> 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), diff --git a/lib/pages/comic_source_page.dart b/lib/pages/comic_source_page.dart index 33e57e4..598df91 100644 --- a/lib/pages/comic_source_page.dart +++ b/lib/pages/comic_source_page.dart @@ -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: () { diff --git a/lib/pages/favorites/network_favorites_page.dart b/lib/pages/favorites/network_favorites_page.dart index 28d5b20..c29c694 100644 --- a/lib/pages/favorites/network_favorites_page.dart +++ b/lib/pages/favorites/network_favorites_page.dart @@ -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(); @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, - ) ], ), ), diff --git a/lib/pages/history_page.dart b/lib/pages/history_page.dart index dd6fa2f..4107d12 100644 --- a/lib/pages/history_page.dart +++ b/lib/pages/history_page.dart @@ -85,7 +85,7 @@ class _HistoryPageState extends State { 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 { icon: Icons.remove, text: 'Remove'.tl, onClick: () { - HistoryManager().remove( - c.id, - ComicType(c.sourceKey.hashCode), - ); + 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), + ); + } }, ), ]; diff --git a/lib/pages/ranking_page.dart b/lib/pages/ranking_page.dart index 96d2fc3..257f585 100644 --- a/lib/pages/ranking_page.dart +++ b/lib/pages/ranking_page.dart @@ -38,23 +38,23 @@ class _RankingPageState extends State { @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( - loadPage: data.rankingData!.load == null - ? null - : (i) => data.rankingData!.load!(optionValue, i), - loadNext: data.rankingData!.loadWithNext == null - ? null - : (i) => data.rankingData!.loadWithNext!(optionValue, i), - ), - ), - ], + 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), + loadNext: data.rankingData!.loadWithNext == null + ? null + : (i) => data.rankingData!.loadWithNext!(optionValue, i), ), ); }