diff --git a/assets/translation.json b/assets/translation.json index aa9f35c..bfc890f 100644 --- a/assets/translation.json +++ b/assets/translation.json @@ -369,7 +369,10 @@ "Explore Page": "探索页面", "Categories Page": "分类页面", "Convert to local": "转换为本地", - "Refresh": "刷新" + "Refresh": "刷新", + "Paging": "分页", + "Continuous": "连续", + "Display mode of comic list": "漫画列表的显示模式" }, "zh_TW": { "Home": "首頁", @@ -741,6 +744,9 @@ "Explore Page": "探索頁面", "Categories Page": "分類頁面", "Convert to local": "轉換為本地", - "Refresh": "刷新" + "Refresh": "刷新", + "Paging": "分頁", + "Continuous": "連續", + "Display mode of comic list": "漫畫列表的顯示模式" } } diff --git a/lib/components/comic.dart b/lib/components/comic.dart index 127e68a..d39bc30 100644 --- a/lib/components/comic.dart +++ b/lib/components/comic.dart @@ -1141,7 +1141,7 @@ class ComicListState extends State { setState(() {}); }); } - if (_loading[page] == true) { + if (_data[page] != null || _loading[page] == true) { return; } _loading[page] = true; @@ -1151,8 +1151,8 @@ class ComicListState extends State { if (!mounted) return; if (res.success) { if (res.data.isEmpty) { - _data[page] = const []; setState(() { + _data[page] = const []; _maxPage = page; }); } else { @@ -1196,12 +1196,18 @@ class ComicListState extends State { if (res.subData == null) { _maxPage = _data.length; } else { + print("next page: ${_data.length}"); _nextUrl = res.subData; } } @override Widget build(BuildContext context) { + var type = appdata.settings['comicListDisplayMode']; + return type == 'paging' ? buildPagingMode() : buildContinuousMode(); + } + + Widget buildPagingMode() { if (_error != null) { return Column( children: [ @@ -1250,6 +1256,85 @@ class ComicListState extends State { ], ); } + + Widget buildContinuousMode() { + if (_error != null && _data.isEmpty) { + return Column( + children: [ + if (widget.errorLeading != null) widget.errorLeading!, + _buildPageSelector(), + Expanded( + child: NetworkError( + withAppbar: false, + message: _error!, + retry: () { + setState(() { + _error = null; + }); + }, + ), + ), + ], + ); + } + if (_data[_page] == null) { + _loadPage(_page); + return Column( + children: [ + if (widget.errorLeading != null) widget.errorLeading!, + const Expanded( + child: Center( + child: CircularProgressIndicator(), + ), + ), + ], + ); + } + return SmoothCustomScrollView( + key: enablePageStorage ? PageStorageKey('scroll$_page') : null, + controller: widget.controller, + slivers: [ + if (widget.leadingSliver != null) widget.leadingSliver!, + SliverGridComics( + comics: _data.values.expand((element) => element).toList(), + menuBuilder: widget.menuBuilder, + onLastItemBuild: () { + if (_error == null && (_maxPage == null || _page < _maxPage!)) { + _loadPage(_data.length + 1); + } + }, + ), + if (_error != null) + SliverToBoxAdapter( + child: Column( + children: [ + Row( + children: [ + const Icon(Icons.error_outline), + const SizedBox(width: 8), + Expanded(child: Text(_error!, maxLines: 3)), + ], + ), + const SizedBox(height: 8), + Center( + child: OutlinedButton( + onPressed: () { + setState(() { + _error = null; + }); + }, + child: Text("Retry".tl), + ), + ), + ], + ).paddingHorizontal(16).paddingVertical(8), + ) + else if (_maxPage == null || _page < _maxPage!) + const SliverListLoadingIndicator(), + if (widget.trailingSliver != null) widget.trailingSliver!, + ], + ); + } } class StarRating extends StatelessWidget { diff --git a/lib/foundation/appdata.dart b/lib/foundation/appdata.dart index 718eb07..6959be4 100644 --- a/lib/foundation/appdata.dart +++ b/lib/foundation/appdata.dart @@ -167,6 +167,7 @@ class Settings with ChangeNotifier { 'preloadImageCount': 4, 'followUpdatesFolder': null, 'initialPage': '0', + 'comicListDisplayMode': 'paging', // paging, continuous }; operator [](String key) { diff --git a/lib/pages/settings/explore_settings.dart b/lib/pages/settings/explore_settings.dart index 6721a5e..da8e2bf 100644 --- a/lib/pages/settings/explore_settings.dart +++ b/lib/pages/settings/explore_settings.dart @@ -90,6 +90,14 @@ class _ExploreSettingsState extends State { '3': "Categories Page".tl, }, ).toSliver(), + SelectSetting( + title: "Display mode of comic list".tl, + settingKey: "comicListDisplayMode", + optionTranslation: { + "paging": "Paging".tl, + "Continuous": "Continuous".tl, + }, + ).toSliver(), ], ); }