diff --git a/assets/locale/en.json b/assets/locale/en.json index 58df45c48..6aec62a17 100644 --- a/assets/locale/en.json +++ b/assets/locale/en.json @@ -257,6 +257,7 @@ "changedthread": "Number of Threads have changed!", "exportlog": "Export Log Record", "thumbnailslidersize": "Thumbnail Slider Size", + "verylarge": "Very Large", "large": "Large", "middle": "Middle", "small": "Small", diff --git a/assets/locale/eo.json b/assets/locale/eo.json index 3cd745551..cac748b3f 100644 --- a/assets/locale/eo.json +++ b/assets/locale/eo.json @@ -257,6 +257,7 @@ "changedthread": "Number of Threads have changed!", "exportlog": "Export Log Record", "thumbnailslidersize": "Thumbnail Slider Size", + "verylarge": "Very Large", "large": "Large", "middle": "Middle", "small": "Small", diff --git a/assets/locale/it.json b/assets/locale/it.json index 021d78c46..020f13ff8 100644 --- a/assets/locale/it.json +++ b/assets/locale/it.json @@ -257,6 +257,7 @@ "changedthread": "Number of Threads have changed!", "exportlog": "Export Log Record", "thumbnailslidersize": "Thumbnail Slider Size", + "verylarge": "Very Large", "large": "Large", "middle": "Middle", "small": "Small", diff --git a/assets/locale/ja.json b/assets/locale/ja.json index 3c9e2f97f..968776aea 100644 --- a/assets/locale/ja.json +++ b/assets/locale/ja.json @@ -257,6 +257,7 @@ "changedthread": "Number of Threads have changed!", "exportlog": "Export Log Record", "thumbnailslidersize": "Thumbnail Slider Size", + "verylarge": "Very Large", "large": "Large", "middle": "Middle", "small": "Small", diff --git a/assets/locale/ko.json b/assets/locale/ko.json index dabe323c9..b878806fa 100644 --- a/assets/locale/ko.json +++ b/assets/locale/ko.json @@ -257,6 +257,7 @@ "changedthread": "스레드 개수를 변경했습니다!", "exportlog": "로그 기록 내보내기", "thumbnailslidersize": "썸네일 슬라이드 크기", + "verylarge": "매우 크게", "large": "크게", "middle": "중간", "small": "작게", diff --git a/assets/locale/pt.json b/assets/locale/pt.json index 4037208a6..d2c8de5b4 100644 --- a/assets/locale/pt.json +++ b/assets/locale/pt.json @@ -257,6 +257,7 @@ "changedthread": "O número de processos mudou!", "exportlog": "Exportar registro de log", "thumbnailslidersize": "Tamanho da miniatura do controle deslizante", + "verylarge": "Venti", "large": "Grande", "middle": "Médio", "small": "Pequeno", diff --git a/assets/locale/zh.json b/assets/locale/zh.json index b37b487fe..2224d9d80 100644 --- a/assets/locale/zh.json +++ b/assets/locale/zh.json @@ -257,6 +257,7 @@ "changedthread": "Number of Threads have changed!", "exportlog": "Export Log Record", "thumbnailslidersize": "Thumbnail Slider Size", + "verylarge": "Very Large", "large": "Large", "middle": "Middle", "small": "Small", diff --git a/assets/locale/zh_Hans.json b/assets/locale/zh_Hans.json index e7ba16080..24cca0f17 100644 --- a/assets/locale/zh_Hans.json +++ b/assets/locale/zh_Hans.json @@ -257,6 +257,7 @@ "changedthread": "Number of Threads have changed!", "exportlog": "Export Log Record", "thumbnailslidersize": "Thumbnail Slider Size", + "verylarge": "Very Large", "large": "Large", "middle": "Middle", "small": "Small", diff --git a/assets/locale/zh_Hant.json b/assets/locale/zh_Hant.json index 2ea14c0c7..53ff783a3 100644 --- a/assets/locale/zh_Hant.json +++ b/assets/locale/zh_Hant.json @@ -257,6 +257,7 @@ "changedthread": "Number of Threads have changed!", "exportlog": "Export Log Record", "thumbnailslidersize": "Thumbnail Slider Size", + "verylarge": "Very Large", "large": "Large", "middle": "Middle", "small": "Small", diff --git a/lib/pages/artist_info/artist_info_page.dart b/lib/pages/artist_info/artist_info_page.dart index 6071b1e17..f59e21b16 100644 --- a/lib/pages/artist_info/artist_info_page.dart +++ b/lib/pages/artist_info/artist_info_page.dart @@ -463,14 +463,16 @@ class _ArtistInfoPageState extends State { Widget queryResult() { final width = MediaQuery.of(context).size.width; - var axis1 = charts.AxisSpec( + final maxItemCount = + MediaQuery.of(context).orientation == Orientation.landscape ? 8 : 6; + final axis1 = charts.AxisSpec( renderSpec: charts.GridlineRendererSpec( labelStyle: charts.TextStyleSpec( fontSize: isExpanded ? 10 : 14, color: charts.MaterialPalette.white), lineStyle: const charts.LineStyleSpec( color: charts.MaterialPalette.transparent))); - var axis2 = const charts.NumericAxisSpec( + const axis2 = charts.NumericAxisSpec( renderSpec: charts.GridlineRendererSpec( labelStyle: charts.TextStyleSpec( fontSize: 10, color: charts.MaterialPalette.white), @@ -566,7 +568,7 @@ class _ArtistInfoPageState extends State { expanded: Column(children: [ articleArea(), Visibility( - visible: cc.length > 6, + visible: cc.length > maxItemCount, child: more(() => ArticleListPage( cc: cc, name: (widget.isGroup @@ -713,6 +715,8 @@ class _ArtistInfoPageState extends State { final windowWidth = MediaQuery.of(context).size.width; final columnCount = MediaQuery.of(context).orientation == Orientation.landscape ? 4 : 3; + final maxItemCount = + MediaQuery.of(context).orientation == Orientation.landscape ? 8 : 6; return LiveGrid( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), @@ -720,7 +724,7 @@ class _ArtistInfoPageState extends State { showItemInterval: const Duration(milliseconds: 50), showItemDuration: const Duration(milliseconds: 150), visibleFraction: 0.001, - itemCount: min(cc.length, 6), + itemCount: min(cc.length, maxItemCount), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: columnCount, crossAxisSpacing: 8, diff --git a/lib/pages/download/download_page.dart b/lib/pages/download/download_page.dart index 873f61de4..7273015fd 100644 --- a/lib/pages/download/download_page.dart +++ b/lib/pages/download/download_page.dart @@ -12,6 +12,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:intl/intl.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -285,7 +286,16 @@ class _DownloadPageState extends ThemeSwitchableState if (Settings.downloadResultType == 0 || Settings.downloadResultType == 1) { if (Settings.downloadAlignType != 0 && Settings.downloadResultType == 0) { - return _panelGroupBy(); + return FutureBuilder( + future: getGroupBy(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const SliverToBoxAdapter(child: SizedBox.shrink()); + } + + return _panelGroupBy(snapshot.data!); + }, + ); } var mm = Settings.downloadResultType == 0 ? 3 : 2; @@ -405,7 +415,29 @@ class _DownloadPageState extends ThemeSwitchableState throw Exception('unreachable'); } - List<(String, List)> getGroupBy() { + Future)>> getGroupBy() async { + final user = await User.getInstance(); + final userlog = await user.getUserLog(); + final articlereadlog = {}; + + for (var element in userlog) { + final id = int.tryParse(element.articleId()); + if (id == null) { + Logger.warning( + '[download-_applyFilter] articleId is not int type: ${element.articleId()}'); + continue; + } + if (!articlereadlog.containsKey(id)) { + final dt = DateTime.tryParse(element.datetimeStart()); + if (dt != null) { + articlereadlog[id] = dt; + } else { + Logger.warning( + '[download-_applyFilter] datetimeStart is not DateTime type: ${element.datetimeStart()}'); + } + } + } + final groups = filterResult.groupListsBy((e) { final qr = queryResults[int.tryParse(e.url()) ?? -1]; if (qr == null) return 'none'; @@ -424,17 +456,30 @@ class _DownloadPageState extends ThemeSwitchableState return getFirst(qr.groups()); case 3: // page + final pageGroup = e.filesWithoutThumbnail().length ~/ 10; + return '${pageGroup * 10} ~ ${(pageGroup + 1) * 10} Page'; + case 4: // datetime recent - return getFirst(qr.groups()); + if (!articlereadlog.containsKey(qr.id())) { + final downoadDateTime = DateTime.parse(e.dateTime()!); + return DateFormat('yyyy.MM.dd').format(downoadDateTime); + } + return DateFormat('yyyy.MM.dd').format(articlereadlog[qr.id()]!); default: throw Exception('unrechable'); } }); - final groupsSorted = groups.entries.map((e) => (e.key, e.value)).toList() + var groupsSorted = groups.entries.map((e) => (e.key, e.value)).toList() ..sortBy((e) => e.$1); + final reverseOrder = + Settings.downloadAlignType == 3 || Settings.downloadAlignType == 4; + if (reverseOrder) { + groupsSorted = groupsSorted.reversed.toList(); + } + return groupsSorted; } @@ -475,13 +520,13 @@ class _DownloadPageState extends ThemeSwitchableState // updateHeights(); } - void _indexChanged() { + Future _indexChanged() async { final details = indexBarDragListener.dragDetails.value; if (details.action == IndexBarDragDetails.actionDown || details.action == IndexBarDragDetails.actionUpdate) { final tag = details.tag!; - final groupBy = getGroupBy(); + final groupBy = await getGroupBy(); // TODO: More optimize final headerCount = @@ -515,46 +560,42 @@ class _DownloadPageState extends ThemeSwitchableState Widget indexBar() { return Align( alignment: Alignment.centerRight, - child: IndexBar( - // data: widget.indexBarData, - data: getGroupBy().map((e) => e.$1[0].toUpperCase()).toSet().toList(), - // options: const IndexBarOptions( - // needRebuild: true, - // color: Colors.transparent, - // ), - indexBarDragListener: indexBarDragListener, - // height: widget.indexBarHeight, - // itemHeight: widget.indexBarItemHeight, - // margin: widget.indexBarMargin, - // indexHintBuilder: widget.indexHintBuilder, - // indexBarDragListener: dragListener, - // options: widget.indexBarOptions, - // controller: indexBarController, - options: const IndexBarOptions( - needRebuild: true, - selectTextStyle: TextStyle( - fontSize: 12, color: Colors.white, fontWeight: FontWeight.w500), - selectItemDecoration: - BoxDecoration(shape: BoxShape.circle, color: Color(0xFF333333)), - // indexHintWidth: 96, - // indexHintHeight: 97, - // indexHintAlignment: Alignment.centerRight, - // indexHintTextStyle: - // TextStyle(fontSize: 24.0, color: Colors.black87), - // indexHintOffset: Offset(-30, 0), - ), + child: FutureBuilder( + future: getGroupBy(), + builder: (context, snapshot) { + if (!snapshot.hasData) return Container(); + + return IndexBar( + data: snapshot.data! + .map((e) => e.$1[0].toUpperCase()) + .toSet() + .toList(), + indexBarDragListener: indexBarDragListener, + options: const IndexBarOptions( + needRebuild: true, + selectTextStyle: TextStyle( + fontSize: 12, + color: Colors.white, + fontWeight: FontWeight.w500), + selectItemDecoration: BoxDecoration( + shape: BoxShape.circle, color: Color(0xFF333333)), + ), + ); + }, ), ); } - Widget _panelGroupBy() { - var windowWidth = lastWindowWidth = MediaQuery.of(context).size.width; - var mm = Settings.downloadResultType == 0 ? 3 : 2; + Widget _panelGroupBy(List<(String, List)> groupBy) { + final windowWidth = lastWindowWidth = MediaQuery.of(context).size.width; + final columnCount = Settings.downloadResultType == 0 ? 3 : 2; + final effectiveColumnCount = + Settings.useTabletMode ? columnCount * 2 : columnCount; heightRefHeader = null; heightRefArticle = null; - final groupsWidget = getGroupBy().map((e) { + final groupsWidget = groupBy.map((e) { final title = Container( key: heightRefHeader == null ? heightRefHeader ??= GlobalKey() : null, padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), @@ -614,7 +655,7 @@ class _DownloadPageState extends ThemeSwitchableState padding: const EdgeInsets.fromLTRB(8, 4, 8, 16), shrinkWrap: true, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: Settings.useTabletMode ? mm * 2 : mm, + crossAxisCount: effectiveColumnCount, crossAxisSpacing: 8, mainAxisSpacing: 8, childAspectRatio: 3 / 4, @@ -633,7 +674,7 @@ class _DownloadPageState extends ThemeSwitchableState initialStyle: DownloadListItem( showDetail: false, addBottomPadding: false, - width: (windowWidth - 4.0) / mm, + width: (windowWidth - 4.0) / effectiveColumnCount, ), item: e, download: e.download, diff --git a/lib/pages/search/search_page.dart b/lib/pages/search/search_page.dart index 55c608c35..56a5c4199 100644 --- a/lib/pages/search/search_page.dart +++ b/lib/pages/search/search_page.dart @@ -571,18 +571,20 @@ class ResultPanelWidget extends StatelessWidget { @override Widget build(BuildContext context) { - final mm = Settings.searchResultType == 0 ? 3 : 2; + final columnCount = Settings.searchResultType == 0 ? 3 : 2; final windowWidth = MediaQuery.of(context).size.width; switch (Settings.searchResultType) { case 0: case 1: + final simpleModeColumnCount = + Settings.useTabletMode ? columnCount * 2 : columnCount; return SliverPadding( padding: const EdgeInsets.fromLTRB(8, 0, 8, 16), sliver: SliverGrid( key: sliverKey, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: Settings.useTabletMode ? mm * 2 : mm, + crossAxisCount: simpleModeColumnCount, crossAxisSpacing: 8, mainAxisSpacing: 8, childAspectRatio: 3 / 4, @@ -591,9 +593,8 @@ class ResultPanelWidget extends StatelessWidget { (BuildContext context, int index) { return articleItem( index, - mm, windowWidth, - (windowWidth - 4.0) / mm, + (windowWidth - 4.0) / simpleModeColumnCount, alignment: Alignment.bottomCenter, ); }, @@ -631,7 +632,6 @@ class ResultPanelWidget extends StatelessWidget { itemBuilder: (context, index, animation) { return articleItem( index, - mm, windowWidth, (windowWidth - 4.0) / kDetailModeColumnCount, showDetail: Settings.searchResultType >= 3, @@ -648,7 +648,6 @@ class ResultPanelWidget extends StatelessWidget { (BuildContext context, int index) { return articleItem( index, - mm, windowWidth, windowWidth - 4.0, showDetail: Settings.searchResultType >= 3, @@ -669,7 +668,6 @@ class ResultPanelWidget extends StatelessWidget { articleItem( int index, - int mm, double windowWidth, double width, { bool showDetail = false, diff --git a/lib/pages/viewer/horizontal_viewer_page.dart b/lib/pages/viewer/horizontal_viewer_page.dart index 1ab35b135..87aaa06f4 100644 --- a/lib/pages/viewer/horizontal_viewer_page.dart +++ b/lib/pages/viewer/horizontal_viewer_page.dart @@ -186,9 +186,14 @@ class _HorizontalViewerPageState extends State { } if (c.provider.useProvider) { if (c.onTwoPage.value) { + var indexPad = 0; + if (c.secondPageToSecondPage.value) { + indexPad = 1; + } + const evict = [-4, -3, 4, 5]; for (final i in evict) { - final target = c.page.value + i; + final target = c.page.value + i - indexPad; if (target < 0 || c.maxPage <= target || c.urlCache[target] == null) { continue; @@ -199,7 +204,7 @@ class _HorizontalViewerPageState extends State { const precache = [-2, -1, 2, 3]; for (final i in precache) { - final target = c.page.value + i; + final target = c.page.value + i - indexPad; if (target < 0 || c.maxPage <= target || c.urlCache[target] == null) { continue; diff --git a/lib/pages/viewer/overlay/viewer_overlay.dart b/lib/pages/viewer/overlay/viewer_overlay.dart index a44567452..80be7329e 100644 --- a/lib/pages/viewer/overlay/viewer_overlay.dart +++ b/lib/pages/viewer/overlay/viewer_overlay.dart @@ -106,7 +106,7 @@ class _ViewerOverlayState extends State { final statusBarHeight = Settings.disableFullScreen ? MediaQuery.of(context).padding.top : 0; final height = MediaQuery.of(context).size.height; - final thumbHeight = [140, 120, 96][c.thumbSize.value]; + final thumbHeight = [180, 140, 120, 96][c.thumbSize.value]; return Obx( () => AnimatedOpacity( @@ -638,7 +638,7 @@ class _ViewerOverlayState extends State { }, ); - final thumbHeight = [140.0, 120.0, 96.0][c.thumbSize.value]; + final thumbHeight = [180.0, 140.0, 120.0, 96.0][c.thumbSize.value]; return Obx( () => AnimatedOpacity( @@ -739,7 +739,7 @@ class _ViewerOverlayState extends State { } _preprocessImageInfoForFileImage() { - final thumbHeight = [140, 120, 96][c.thumbSize.value]; + final thumbHeight = [180, 140, 120, 96][c.thumbSize.value]; c.thumb.value = Settings.enableThumbSlider; var imageSizes = c.provider.uris.map((e) { @@ -820,7 +820,8 @@ class _ViewerOverlayState extends State { height: double.infinity, isAntiAlias: true, cacheHeight: - ([140, 120, 96][c.thumbSize.value] * 2.0).toInt(), + ([180, 140, 120, 96][c.thumbSize.value] * 2.0) + .toInt(), filterQuality: FilterQuality.high, ), ), diff --git a/lib/pages/viewer/overlay/viewer_setting_panel.dart b/lib/pages/viewer/overlay/viewer_setting_panel.dart index a329533c0..43627179d 100644 --- a/lib/pages/viewer/overlay/viewer_setting_panel.dart +++ b/lib/pages/viewer/overlay/viewer_setting_panel.dart @@ -289,6 +289,7 @@ class _ViewerSettingPanelState extends State { ), trailing: Text( [ + locale.Translations.of(context).trans('verylarge'), locale.Translations.of(context).trans('large'), locale.Translations.of(context).trans('middle'), locale.Translations.of(context).trans('small') diff --git a/lib/settings/settings.dart b/lib/settings/settings.dart index 08e1deb27..15e373ae8 100644 --- a/lib/settings/settings.dart +++ b/lib/settings/settings.dart @@ -237,7 +237,7 @@ class Settings { await _getBool('movetoappbartobottom', Platform.isIOS); showSlider = await _getBool('showslider'); imageQuality = await _getInt('imagequality', 3); - thumbSize = await _getInt('imageQuality', 0); + thumbSize = await _getInt('imageQuality', 1); enableThumbSlider = await _getBool('enableThumbSlider'); showPageNumberIndicator = await _getBool('showPageNumberIndicator', true); showRecordJumpMessage = await _getBool('showRecordJumpMessage', true);