Fix landscape reader layout and wrap long settings labels (#640)

* fix: handle mobile landscape safe area #604

* fix: adjust reader toolbars safe area

* fix: adjust multi-image reader layout after orientation change

* fix: item titles not fully displayed
This commit is contained in:
boa
2025-11-29 14:19:43 +08:00
committed by GitHub
parent 7e928d2c9c
commit b9c06779ad
4 changed files with 75 additions and 42 deletions

View File

@@ -172,6 +172,16 @@ class NaviPaneState extends State<NaviPane>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
onRebuild(context); onRebuild(context);
final mq = MediaQuery.of(context);
final sideInsets =
(App.isMobile && mq.orientation == Orientation.landscape)
? EdgeInsets.only(
left: math.max(
mq.viewPadding.left, mq.systemGestureInsets.left),
right: math.max(
mq.viewPadding.right, mq.systemGestureInsets.right),
)
: EdgeInsets.zero;
return _NaviPopScope( return _NaviPopScope(
action: () { action: () {
if (App.mainNavigatorKey!.currentState!.canPop()) { if (App.mainNavigatorKey!.currentState!.canPop()) {
@@ -185,7 +195,7 @@ class NaviPaneState extends State<NaviPane>
animation: controller, animation: controller,
builder: (context, child) { builder: (context, child) {
final value = controller.value; final value = controller.value;
return Stack( Widget content = Stack(
children: [ children: [
Positioned( Positioned(
left: _kFoldedSideBarWidth * ((value - 2.0).clamp(-1.0, 0.0)), left: _kFoldedSideBarWidth * ((value - 2.0).clamp(-1.0, 0.0)),
@@ -202,6 +212,13 @@ class NaviPaneState extends State<NaviPane>
), ),
], ],
); );
if (sideInsets != EdgeInsets.zero) {
content = Padding(
padding: sideInsets,
child: content,
);
}
return content;
}, },
), ),
); );

View File

@@ -286,8 +286,9 @@ class _GalleryModeState extends State<_GalleryMode>
); );
} }
final viewportSize = MediaQuery.of(context).size;
return PhotoViewGalleryPageOptions.customChild( return PhotoViewGalleryPageOptions.customChild(
childSize: reader.size * 2, childSize: viewportSize,
controller: photoViewControllers[index], controller: photoViewControllers[index],
minScale: PhotoViewComputedScale.contained * 1.0, minScale: PhotoViewComputedScale.contained * 1.0,
maxScale: PhotoViewComputedScale.covered * 10.0, maxScale: PhotoViewComputedScale.covered * 10.0,

View File

@@ -166,40 +166,49 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
decoration: BoxDecoration( decoration: BoxDecoration(
color: context.colorScheme.surface.toOpacity(0.92), color: context.colorScheme.surface.toOpacity(0.92),
border: Border( border: Border(
bottom: BorderSide(color: Colors.grey.toOpacity(0.5), width: 0.5), bottom: BorderSide(
color: Colors.grey.toOpacity(0.5),
width: 0.5,
),
), ),
), ),
child: Row( child: Padding(
children: [ padding: EdgeInsets.only(
const SizedBox(width: 8), left: context.padding.left,
const BackButton(), right: context.padding.right,
const SizedBox(width: 8), ),
Expanded( child: Row(
child: Text( children: [
context.reader.widget.name, const SizedBox(width: 8),
style: ts.s18, const BackButton(),
maxLines: 1, const SizedBox(width: 8),
overflow: TextOverflow.ellipsis, Expanded(
), child: Text(
), context.reader.widget.name,
const SizedBox(width: 8), style: ts.s18,
if (shouldShowChapterComments()) maxLines: 1,
Tooltip( overflow: TextOverflow.ellipsis,
message: "Chapter Comments".tl,
child: IconButton(
icon: const Icon(Icons.comment),
onPressed: openChapterComments,
), ),
), ),
Tooltip( const SizedBox(width: 8),
message: "Settings".tl, if (shouldShowChapterComments())
child: IconButton( Tooltip(
icon: const Icon(Icons.settings), message: "Chapter Comments".tl,
onPressed: openSetting, child: IconButton(
icon: const Icon(Icons.comment),
onPressed: openChapterComments,
),
),
Tooltip(
message: "Settings".tl,
child: IconButton(
icon: const Icon(Icons.settings),
onPressed: openSetting,
),
), ),
), const SizedBox(width: 8),
const SizedBox(width: 8), ],
], ),
), ),
), ),
); );
@@ -520,7 +529,13 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
: null, : null,
), ),
padding: EdgeInsets.only(bottom: context.padding.bottom), padding: EdgeInsets.only(bottom: context.padding.bottom),
child: child, child: Padding(
padding: EdgeInsets.only(
left: context.padding.left,
right: context.padding.right,
),
child: child,
),
), ),
); );
} }
@@ -713,11 +728,12 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
} }
Widget buildEpChangeButton() { Widget buildEpChangeButton() {
final extraWidth = context.padding.left + context.padding.right;
if (context.reader.widget.chapters == null) return const SizedBox(); if (context.reader.widget.chapters == null) return const SizedBox();
switch (showFloatingButtonValue) { switch (showFloatingButtonValue) {
case 0: case 0:
return Container( return Container(
width: 58, width: 58 + extraWidth,
height: 58, height: 58,
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -735,7 +751,7 @@ class _ReaderScaffoldState extends State<_ReaderScaffold> {
case -1: case -1:
case 1: case 1:
return SizedBox( return SizedBox(
width: 58, width: 58 + extraWidth,
height: 58, height: 58,
child: Material( child: Material(
color: Theme.of(context).colorScheme.primaryContainer, color: Theme.of(context).colorScheme.primaryContainer,

View File

@@ -385,17 +385,16 @@ class _SliderSettingState extends State<_SliderSetting> {
: appdata.settings.getReaderSetting( : appdata.settings.getReaderSetting(
widget.comicId!, widget.comicId!,
widget.comicSource!, widget.comicSource!,
widget.settingsIndex, widget.settingsIndex,
)) ))
.toDouble(); .toDouble();
return ListTile( return ListTile(
title: Row( title: Text(
children: [ widget.title,
Text(widget.title), softWrap: true,
const Spacer(), maxLines: 2,
Text(value.toString(), style: ts.s12),
],
), ),
trailing: Text(value.toString(), style: ts.s12),
subtitle: Slider( subtitle: Slider(
value: value, value: value,
onChanged: (value) { onChanged: (value) {