Skip to content

Commit 28fa0ec

Browse files
committed
feat: zoom images
1 parent fbd1cad commit 28fa0ec

File tree

2 files changed

+130
-68
lines changed

2 files changed

+130
-68
lines changed

lib/Screens/Manga/MangaReader/Reader.dart

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class MediaReaderState extends State<MediaReader> {
3636
void initState() {
3737
super.initState();
3838
focusNode.requestFocus();
39+
pageController.addListener(_onPageChanged);
3940
}
4041

4142
@override
@@ -53,26 +54,42 @@ class MediaReaderState extends State<MediaReader> {
5354
child: Stack(
5455
alignment: Alignment.center,
5556
children: [
56-
_buildWebtoonMode(),
57+
InteractiveViewer(
58+
minScale: 0.5,
59+
maxScale: 4,
60+
child: _buildLTRMode(),
61+
),
5762
_buildOverlay(),
5863
],
5964
),
6065
),
6166
);
6267
}
6368

69+
var currentPage = 1;
70+
71+
void _onPageChanged() {
72+
final page = (pageController.page?.round() ?? 0) + 1;
73+
if (page != currentPage) {
74+
setState(() => currentPage = page);
75+
}
76+
}
77+
6478
ScrollController scrollController = ScrollController();
65-
Widget _buildWebtoonMode() {
79+
80+
Widget _buildUPDMode() {
6681
return ScrollConfig(
6782
context,
6883
child: ListView.builder(
84+
reverse: true,
6985
controller: scrollController,
7086
itemCount: widget.pages.length,
7187
itemBuilder: (context, index) {
7288
final page = widget.pages[index];
7389
return Center(
7490
child: ConstrainedBox(
75-
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
91+
constraints:
92+
BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
7693
child: CachedNetworkImage(
7794
imageUrl: page.url,
7895
fit: BoxFit.fitWidth,
@@ -81,11 +98,10 @@ class MediaReaderState extends State<MediaReader> {
8198
child: Center(child: CircularProgressIndicator()),
8299
),
83100
errorWidget: (context, url, error) => Center(
84-
child: Text(
85-
'Failed to load image: $error',
86-
style: TextStyle(color: Colors.red),
87-
)
88-
),
101+
child: Text(
102+
'Failed to load image: $error',
103+
style: TextStyle(color: Colors.red),
104+
)),
89105
),
90106
),
91107
);
@@ -94,6 +110,40 @@ class MediaReaderState extends State<MediaReader> {
94110
);
95111
}
96112

113+
final PageController pageController = PageController();
114+
115+
Widget _buildLTRMode() {
116+
return ScrollConfig(
117+
context,
118+
child: PageView.builder(
119+
controller: pageController,
120+
scrollDirection: Axis.horizontal,
121+
reverse: true,
122+
itemCount: widget.pages.length,
123+
itemBuilder: (context, index) {
124+
final page = widget.pages[index];
125+
return Center(
126+
child: ConstrainedBox(
127+
constraints:
128+
BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
129+
child: CachedNetworkImage(
130+
imageUrl: page.url,
131+
fit: BoxFit.fitWidth,
132+
placeholder: (context, url) => SizedBox(
133+
height: MediaQuery.of(context).size.height / 2,
134+
child: Center(child: CircularProgressIndicator()),
135+
),
136+
errorWidget: (context, url, error) => Center(
137+
child: Text('Failed to load image: $error',
138+
style: TextStyle(color: Colors.red)),
139+
),
140+
),
141+
),
142+
);
143+
},
144+
),
145+
);
146+
}
97147

98148
Widget _buildOverlay() {
99149
return Obx(() {

lib/Screens/Manga/MangaReader/ReaderController.dart

Lines changed: 72 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -157,69 +157,81 @@ class _ReaderControllerState extends State<ReaderController> {
157157
crossAxisAlignment: CrossAxisAlignment.end,
158158
mainAxisAlignment: MainAxisAlignment.spaceBetween,
159159
children: [
160-
previousChapter != null
161-
? Row(
162-
children: [
163-
_buildControlButton(
164-
icon: Icons.skip_previous_rounded,
165-
color: Colors.white,
166-
onPressed: () {
167-
onChapterClick(
168-
context,
169-
previousChapter,
170-
source,
171-
media,
172-
() => Get.back(),
173-
);
174-
},
175-
),
176-
SizedBox(width: 12),
177-
Text(
178-
previousChapter.title.toString(),
179-
style: const TextStyle(
180-
color: Colors.white,
181-
fontSize: 14,
182-
fontWeight: FontWeight.bold,
183-
),
184-
maxLines: 1,
185-
overflow: TextOverflow.ellipsis,
186-
),
187-
],
188-
)
189-
: SizedBox(),
190-
nextChapter != null
191-
? Row(
192-
children: [
193-
Text(
194-
nextChapter.title.toString(),
195-
style: const TextStyle(
196-
color: Colors.white,
197-
fontSize: 14,
198-
fontWeight: FontWeight.bold,
199-
),
200-
maxLines: 1,
201-
overflow: TextOverflow.ellipsis,
202-
),
203-
SizedBox(width: 12),
204-
_buildControlButton(
205-
icon: Icons.skip_next_rounded,
206-
color: Colors.white,
207-
onPressed: () {
208-
onChapterClick(
209-
context,
210-
nextChapter,
211-
source,
212-
media,
213-
() => Get.back(),
214-
);
215-
},
216-
),
217-
],
218-
)
219-
: SizedBox(),
160+
Visibility(
161+
visible: previousChapter != null,
162+
child: Row(
163+
children: [
164+
_buildControlButton(
165+
icon: Icons.skip_previous_rounded,
166+
color: Colors.white,
167+
onPressed: () {
168+
onChapterClick(
169+
context,
170+
previousChapter!,
171+
source,
172+
media,
173+
() => Get.back(),
174+
);
175+
},
176+
),
177+
SizedBox(width: 12),
178+
Text(
179+
previousChapter?.title.toString() ?? '',
180+
style: const TextStyle(
181+
color: Colors.white,
182+
fontSize: 14,
183+
fontWeight: FontWeight.bold,
184+
),
185+
maxLines: 1,
186+
overflow: TextOverflow.ellipsis,
187+
),
188+
],
189+
),
190+
),
191+
Visibility(
192+
visible: nextChapter != null,
193+
child: Row(
194+
children: [
195+
Text(
196+
nextChapter?.title.toString() ?? '',
197+
style: const TextStyle(
198+
color: Colors.white,
199+
fontSize: 14,
200+
fontWeight: FontWeight.bold,
201+
),
202+
maxLines: 1,
203+
overflow: TextOverflow.ellipsis,
204+
),
205+
const SizedBox(width: 12),
206+
_buildControlButton(
207+
icon: Icons.skip_next_rounded,
208+
color: Colors.white,
209+
onPressed: () {
210+
onChapterClick(
211+
context,
212+
nextChapter!,
213+
source,
214+
media,
215+
() => Get.back(),
216+
);
217+
},
218+
),
219+
],
220+
),
221+
)
220222
],
221223
),
222224
),
225+
Center(
226+
child: Text(
227+
"${widget.reader.currentPage}/${pages.length}",
228+
style: const TextStyle(
229+
color: Colors.white,
230+
fontSize: 14,
231+
fontWeight: FontWeight.bold,
232+
),
233+
),
234+
),
223235
],
224236
);
225237
}

0 commit comments

Comments
 (0)