Skip to content

Commit

Permalink
In the top2bottom layout mode, the reading page can now support custo…
Browse files Browse the repository at this point in the history
…mizing the width of the image area

阅读页在从上至下布局模式下,现在可以支持自定义图片区域宽度
  • Loading branch information
jiangtian616 committed Dec 30, 2023
1 parent a9cbeff commit 3f39acc
Show file tree
Hide file tree
Showing 22 changed files with 212 additions and 72 deletions.
3 changes: 2 additions & 1 deletion changelog/v7.4.8+147.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
- 移动端支持自定义阅读页亮度
- 现在所有平台和布局模式下均可以自定义鼠标滚轮滚动速度
- 优化取消收藏时的文案
- 阅读页在从上至下布局模式下,现在可以支持自定义图片区域宽度
- 优化保存图片时的图片命名规则
- 优化解压归档时的icon显示
- 收藏页和关注页搜索不再继承关键字
Expand All @@ -16,6 +16,7 @@

- Support customizing the brightness of the reading page on the mobile terminal
- Now you can customize the mouse wheel scrolling speed in all platforms and layout modes
- In the top to bottom layout mode, the reading page can now support customizing the width of the image area
- Optimize the toast message when canceling favorites
- Optimize the image naming rules when saving images
- Optimize the icon display when decompressing archives
Expand Down
1 change: 1 addition & 0 deletions lib/src/config/ui_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ class UIConfig {
static const int searchPageAnimationDuration = 250;

/// Read page
static const Color readPageBackGroundColor = Colors.black;
static const Color readPageForeGroundColor = Colors.white;

static Color get readPageMenuColor => Colors.black.withOpacity(0.85);
Expand Down
1 change: 1 addition & 0 deletions lib/src/l18n/en_US.dart
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ class en_US {
'landscape': 'Landscape',
'portrait': 'Portrait',
'readDirection': 'Read Direction',
'imageRegionWidthRatio': 'Image Region Width Ratio',
'useThirdPartyViewer': 'Use Custom Viewer',
'thirdPartyViewerPath': 'Custom Viewer Path(Executable file)',
'showThumbnails': 'Show Thumbnails',
Expand Down
1 change: 1 addition & 0 deletions lib/src/l18n/ko_KR.dart
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ class ko_KR {
'landscape': 'Landscape',
'portrait': 'Portrait',
'readDirection': '읽는 방향',
'imageRegionWidthRatio': 'Image Region Width Ratio',
'useThirdPartyViewer': '커스텀 뷰어 사용',
'thirdPartyViewerPath': '커스텀 뷰어 경로(실행 파일)',
'showThumbnails': '섬네일 보기',
Expand Down
1 change: 1 addition & 0 deletions lib/src/l18n/pt_BR.dart
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ class pt_BR {
'landscape': 'Landscape',
'portrait': 'Portrait',
'readDirection': 'Direção da leitura',
'imageRegionWidthRatio': 'Image Region Width Ratio',
'useThirdPartyViewer': 'Usar visualizador personaliado',
'thirdPartyViewerPath': 'Localização do visualizador personalizado(Arquivo executável)',
'showThumbnails': 'Mostrar miniaturas',
Expand Down
1 change: 1 addition & 0 deletions lib/src/l18n/zh_CN.dart
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ class zh_CN {
'landscape': '横屏',
'portrait': '竖屏',
'readDirection': '阅读方向',
'imageRegionWidthRatio': '图片区域宽度比例',
'useThirdPartyViewer': '使用第三方阅读器',
'thirdPartyViewerPath': '第三方阅读器路径(可执行文件)',
'showThumbnails': '显示缩略图',
Expand Down
1 change: 1 addition & 0 deletions lib/src/l18n/zh_TW.dart
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ class zh_TW {
'landscape': '橫屏',
'portrait': '豎屏',
'readDirection': '閱讀方向',
'imageRegionWidthRatio': '圖片區域寬度比例',
'useThirdPartyViewer': '使用第三方閱讀器',
'thirdPartyViewerPath': '第三方閱讀器路徑(可執行文件)',
'showThumbnails': '顯示快取圖',
Expand Down
8 changes: 4 additions & 4 deletions lib/src/pages/read/layout/base/base_layout_logic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ abstract class BaseLayoutLogic extends GetxController with GetTickerProviderStat
(_) => Share.shareFiles(
[path],
text: '$index${extension(readPageState.images[index]!.url)}',
sharePositionOrigin: Rect.fromLTWH(0, 0, fullScreenWidth, readPageState.imageRegionSize.height * 2 / 3),
sharePositionOrigin: Rect.fromLTWH(0, 0, fullScreenWidth, readPageState.displayRegionSize.height * 2 / 3),
),
);
}
Expand All @@ -214,7 +214,7 @@ abstract class BaseLayoutLogic extends GetxController with GetTickerProviderStat
galleryDownloadService.galleryDownloadInfos[readPageState.readPageInfo.gid!]!.images[index]!.path!),
],
text: basename(galleryDownloadService.galleryDownloadInfos[readPageState.readPageInfo.gid!]!.images[index]!.path!),
sharePositionOrigin: Rect.fromLTWH(0, 0, fullScreenWidth, readPageState.imageRegionSize.height * 2 / 3),
sharePositionOrigin: Rect.fromLTWH(0, 0, fullScreenWidth, readPageState.displayRegionSize.height * 2 / 3),
);
}

Expand Down Expand Up @@ -290,15 +290,15 @@ abstract class BaseLayoutLogic extends GetxController with GetTickerProviderStat
if (readPageState.imageContainerSizes[imageIndex] != null) {
return readPageState.imageContainerSizes[imageIndex]!;
}
return Size(double.infinity, readPageState.imageRegionSize.height / 2);
return Size(double.infinity, readPageState.displayRegionSize.height / 2);
}

/// Compute image container size
FittedSizes getImageFittedSize(Size imageSize) {
return applyBoxFit(
BoxFit.contain,
Size(imageSize.width, imageSize.height),
Size(readPageState.imageRegionSize.width, double.infinity),
Size(readPageState.displayRegionSize.width, double.infinity),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ class HorizontalDoubleColumnLayoutLogic extends BaseLayoutLogic {
BoxFit.contain,
Size(imageSize.width, imageSize.height),
Size(
isSpreadPage ? readPageState.imageRegionSize.width : (readPageState.imageRegionSize.width - ReadSetting.imageSpace.value) / 2,
readPageState.imageRegionSize.height,
isSpreadPage ? readPageState.displayRegionSize.width : (readPageState.displayRegionSize.width - ReadSetting.imageSpace.value) / 2,
readPageState.displayRegionSize.height,
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class HorizontalListLayoutLogic extends BaseLayoutLogic {
return applyBoxFit(
BoxFit.contain,
Size(imageSize.width, imageSize.height),
Size(double.infinity, readPageState.imageRegionSize.height),
Size(double.infinity, readPageState.displayRegionSize.height),
);
}
}
68 changes: 41 additions & 27 deletions lib/src/pages/read/layout/vertical_list/vertical_list_layout.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jhentai/src/config/ui_config.dart';
import 'package:jhentai/src/model/read_page_info.dart';
import 'package:jhentai/src/pages/read/layout/vertical_list/vertical_list_layout_state.dart';
import 'package:photo_view/photo_view_gallery.dart';
Expand All @@ -20,34 +21,47 @@ class VerticalListLayout extends BaseLayout {

@override
Widget buildBody(BuildContext context) {
/// user PhotoViewGallery to scale up the whole gallery list, so set itemCount to 1
return PhotoViewGallery.builder(
itemCount: 1,
builder: (_, __) => PhotoViewGalleryPageOptions.customChild(
controller: state.photoViewController,
initialScale: 1.0,
minScale: 1.0,
maxScale: 2.5,
scaleStateCycle: ReadSetting.enableDoubleTapToScaleUp.isTrue ? logic.scaleStateCycle : null,
enableTapDragZoom: ReadSetting.enableTapDragToScaleUp.isTrue,
child: EHWheelSpeedControllerForReadPage(
scrollController: state.itemScrollController,
child: EHScrollablePositionedList.separated(
physics: const ClampingScrollPhysics(),
minCacheExtent: readPageState.readPageInfo.mode == ReadMode.online
? ReadSetting.preloadDistance * screenHeight * 1
: GetPlatform.isIOS
? 3 * screenHeight
: 8 * screenHeight,
initialScrollIndex: readPageState.readPageInfo.initialIndex,
itemCount: readPageState.readPageInfo.pageCount,
itemScrollController: state.itemScrollController,
itemPositionsListener: state.itemPositionsListener,
itemBuilder: (context, index) =>
readPageState.readPageInfo.mode == ReadMode.online ? buildItemInOnlineMode(context, index) : buildItemInLocalMode(context, index),
separatorBuilder: (_, __) => Obx(() => SizedBox(height: ReadSetting.imageSpace.value.toDouble())),
return GetBuilder<VerticalListLayoutLogic>(
id: logic.verticalLayoutId,
builder: (_) => Row(
children: [
Expanded(flex: 100 - ReadSetting.imageRegionWidthRatio.value, child: Container(color: UIConfig.readPageBackGroundColor)),

/// user PhotoViewGallery to scale up the whole gallery list, so set itemCount to 1
Expanded(
flex: ReadSetting.imageRegionWidthRatio.value * 2,
child: PhotoViewGallery.builder(
itemCount: 1,
builder: (_, __) => PhotoViewGalleryPageOptions.customChild(
controller: state.photoViewController,
initialScale: 1.0,
minScale: 1.0,
maxScale: 2.5,
scaleStateCycle: ReadSetting.enableDoubleTapToScaleUp.isTrue ? logic.scaleStateCycle : null,
enableTapDragZoom: ReadSetting.enableTapDragToScaleUp.isTrue,
child: EHWheelSpeedControllerForReadPage(
scrollController: state.itemScrollController,
child: EHScrollablePositionedList.separated(
physics: const ClampingScrollPhysics(),
minCacheExtent: readPageState.readPageInfo.mode == ReadMode.online
? ReadSetting.preloadDistance * screenHeight * 1
: GetPlatform.isIOS
? 3 * screenHeight
: 8 * screenHeight,
initialScrollIndex: readPageState.readPageInfo.initialIndex,
itemCount: readPageState.readPageInfo.pageCount,
itemScrollController: state.itemScrollController,
itemPositionsListener: state.itemPositionsListener,
itemBuilder: (context, index) =>
readPageState.readPageInfo.mode == ReadMode.online ? buildItemInOnlineMode(context, index) : buildItemInLocalMode(context, index),
separatorBuilder: (_, __) => Obx(() => SizedBox(height: ReadSetting.imageSpace.value.toDouble())),
),
),
),
),
),
),
Expanded(flex: 100 - ReadSetting.imageRegionWidthRatio.value, child: Container(color: UIConfig.readPageBackGroundColor)),
],
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import 'dart:async';
import 'dart:math';

import 'package:collection/collection.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:jhentai/src/extension/get_logic_extension.dart';
import 'package:jhentai/src/pages/read/layout/vertical_list/vertical_list_layout_state.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

Expand All @@ -11,8 +13,12 @@ import '../../../../utils/screen_size_util.dart';
import '../base/base_layout_logic.dart';

class VerticalListLayoutLogic extends BaseLayoutLogic {
final String verticalLayoutId = 'verticalLayoutId';

VerticalListLayoutState state = VerticalListLayoutState();

late Worker imageRegionWidthRatioListener;

@override
void onInit() {
super.onInit();
Expand All @@ -21,6 +27,16 @@ class VerticalListLayoutLogic extends BaseLayoutLogic {
state.itemPositionsListener.itemPositions.addListener(_readProgressListener);
}

@override
void onReady() {
super.onReady();

imageRegionWidthRatioListener = ever(ReadSetting.imageRegionWidthRatio, (int value) {
readPageLogic.clearImageContainerSized();
updateSafely([verticalLayoutId]);
});
}

@override
void toLeft() {
toPrev();
Expand Down Expand Up @@ -213,4 +229,23 @@ class VerticalListLayoutLogic extends BaseLayoutLogic {
double _getVisibleHeight() {
return screenHeight - Get.mediaQuery.padding.bottom - (ReadSetting.enableImmersiveMode.isTrue ? 0 : Get.mediaQuery.padding.top);
}

/// Compute image container size when we haven't parsed image's size
@override
Size getPlaceHolderSize(int imageIndex) {
if (readPageState.imageContainerSizes[imageIndex] != null) {
return readPageState.imageContainerSizes[imageIndex]!;
}
return Size(readPageState.displayRegionSize.width * ReadSetting.imageRegionWidthRatio.value / 100, readPageState.displayRegionSize.height / 2);
}

/// Compute image container size
@override
FittedSizes getImageFittedSize(Size imageSize) {
return applyBoxFit(
BoxFit.contain,
Size(imageSize.width, imageSize.height),
Size(readPageState.displayRegionSize.width * ReadSetting.imageRegionWidthRatio.value / 100, double.infinity),
);
}
}
2 changes: 1 addition & 1 deletion lib/src/pages/read/read_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class _ReadPageState extends State<ReadPage> with ScrollStatusListener, WindowLi
return LayoutBuilder(
builder: (context, constraints) {
logic.clearImageContainerSized();
state.imageRegionSize = Size(constraints.maxWidth, constraints.maxHeight);
state.displayRegionSize = Size(constraints.maxWidth, constraints.maxHeight);

if (ReadSetting.readDirection.value == ReadDirection.top2bottomList) {
return VerticalListLayout();
Expand Down
2 changes: 1 addition & 1 deletion lib/src/pages/read/read_page_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ReadPageState with ScrollStatusListerState {
bool displayFirstPageAlone = ReadSetting.displayFirstPageAlone.value;
FocusNode focusNode = FocusNode();

late Size imageRegionSize;
late Size displayRegionSize;

final EHItemScrollController thumbnailsScrollController = EHItemScrollController();
final ItemPositionsListener thumbnailPositionsListener = ItemPositionsListener.create();
Expand Down
28 changes: 2 additions & 26 deletions lib/src/pages/setting/eh/tagsets/tag_sets_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:jhentai/src/utils/search_util.dart';
import 'package:jhentai/src/widget/eh_wheel_speed_controller.dart';

import '../../../../utils/route_util.dart';
import '../../../../utils/text_input_formatter.dart';
import '../../../../widget/loading_state_indicator.dart';

class TagSetsPage extends StatelessWidget {
Expand Down Expand Up @@ -181,7 +182,7 @@ class _Tag extends StatelessWidget {
textAlign: TextAlign.center,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[\d-]')),
NumberRangeTextInputFormatter(minValue: -99, maxValue: 99),
IntRangeTextInputFormatter(minValue: -99, maxValue: 99),
],
onSubmitted: onWeightUpdated,
),
Expand All @@ -191,31 +192,6 @@ class _Tag extends StatelessWidget {

enum TagSetStatus { watched, hidden, nope }

class NumberRangeTextInputFormatter extends TextInputFormatter {
double? minValue;
double? maxValue;

NumberRangeTextInputFormatter({this.minValue, this.maxValue});

@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
if (newValue.text.isEmpty || (minValue != null && minValue! < 0 && newValue.text == '-')) {
return newValue;
}

double newNum = double.tryParse(newValue.text) ?? -100;

if (minValue != null && newNum < minValue!) {
return oldValue;
}
if (maxValue != null && newNum > maxValue!) {
return oldValue;
}

return newValue;
}
}

class _ColorSettingDialog extends StatefulWidget {
final Color initialColor;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import 'package:jhentai/src/config/ui_config.dart';
import 'package:jhentai/src/extension/widget_extension.dart';
import 'package:jhentai/src/setting/mouse_setting.dart';

import '../../../utils/text_input_formatter.dart';
import '../../../utils/toast_util.dart';
import '../eh/tagsets/tag_sets_page.dart';

class SettingMouseWheelPage extends StatelessWidget {
const SettingMouseWheelPage({Key? key}) : super(key: key);
Expand All @@ -32,7 +32,7 @@ class SettingMouseWheelPage extends StatelessWidget {
controller: wheelScrollSpeedController,
decoration: const InputDecoration(isDense: true, labelStyle: TextStyle(fontSize: 12)),
textAlign: TextAlign.center,
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'\d|\.')), NumberRangeTextInputFormatter(minValue: 0)],
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'\d|\.')), DoubleRangeTextInputFormatter(minValue: 0)],
onSubmitted: (_) {
double? value = double.tryParse(wheelScrollSpeedController.value.text);
if (value == null) {
Expand Down
7 changes: 4 additions & 3 deletions lib/src/pages/setting/network/setting_network_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import 'package:jhentai/src/setting/network_setting.dart';

import '../../../routes/routes.dart';
import '../../../utils/route_util.dart';
import '../../../utils/text_input_formatter.dart';
import '../../../utils/toast_util.dart';
import '../eh/tagsets/tag_sets_page.dart';

class SettingNetworkPage extends StatelessWidget {
final TextEditingController proxyAddressController = TextEditingController(text: NetworkSetting.proxyAddress.value);
Expand Down Expand Up @@ -93,11 +93,12 @@ class SettingNetworkPage extends StatelessWidget {
width: 50,
child: TextField(
controller: connectTimeoutController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(isDense: true, labelStyle: TextStyle(fontSize: 12)),
textAlign: TextAlign.center,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
NumberRangeTextInputFormatter(minValue: 0),
IntRangeTextInputFormatter(minValue: 0),
],
),
),
Expand Down Expand Up @@ -133,7 +134,7 @@ class SettingNetworkPage extends StatelessWidget {
textAlign: TextAlign.center,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
NumberRangeTextInputFormatter(minValue: 0),
IntRangeTextInputFormatter(minValue: 0),
],
),
),
Expand Down
Loading

0 comments on commit 3f39acc

Please sign in to comment.