diff --git a/lib/pages/illust_page.dart b/lib/pages/illust_page.dart index b156765..4397ca6 100644 --- a/lib/pages/illust_page.dart +++ b/lib/pages/illust_page.dart @@ -24,12 +24,14 @@ import '../components/illust_widget.dart'; import '../components/md.dart'; import '../components/ugoira.dart'; - const _kBottomBarHeight = 64.0; class IllustGalleryPage extends StatefulWidget { - const IllustGalleryPage({required this.illusts, required this.initialPage, - this.nextUrl, super.key}); + const IllustGalleryPage( + {required this.illusts, + required this.initialPage, + this.nextUrl, + super.key}); final List illusts; @@ -55,50 +57,47 @@ class _IllustGalleryPageState extends State { illusts = List.from(widget.illusts); controller = PageController(initialPage: widget.initialPage); nextUrl = widget.nextUrl; - if(nextUrl == "end") { + if (nextUrl == "end") { nextUrl = null; } super.initState(); } + void nextPage() { + var length = illusts.length; + if (controller.page == length - 1) return; + controller.nextPage( + duration: const Duration(milliseconds: 200), curve: Curves.ease); + } + + void previousPage() { + if (controller.page == 0) return; + controller.previousPage( + duration: const Duration(milliseconds: 200), curve: Curves.ease); + } + @override Widget build(BuildContext context) { var length = illusts.length; - if(nextUrl != null) { + if (nextUrl != null) { length++; } - return CallbackShortcuts( - bindings: { - LogicalKeySet(LogicalKeyboardKey.arrowLeft): () { - if(controller.page == 0) return; - controller.previousPage( - duration: const Duration(milliseconds: 200), curve: Curves.ease); - }, - LogicalKeySet(LogicalKeyboardKey.arrowRight): () { - if(controller.page == length-1) return; - controller.nextPage( - duration: const Duration(milliseconds: 200), curve: Curves.ease); + return PageView.builder( + controller: controller, + itemCount: length, + itemBuilder: (context, index) { + if (index == illusts.length) { + return buildLast(); } + return IllustPage(illusts[index], + nextPage: nextPage, previousPage: previousPage); }, - child: Focus( - autofocus: true, - child: PageView.builder( - controller: controller, - itemCount: length, - itemBuilder: (context, index) { - if(index == illusts.length) { - return buildLast(); - } - return IllustPage(illusts[index]); - }, - ), - ), ); } - Widget buildLast(){ - if(nextUrl == null) { + Widget buildLast() { + if (nextUrl == null) { return const SizedBox(); } load(); @@ -108,13 +107,13 @@ class _IllustGalleryPageState extends State { } void load() async { - if(loading) return; + if (loading) return; loading = true; var res = await Network().getIllustsWithNextUrl(nextUrl!); loading = false; - if(res.error) { - if(mounted) { + if (res.error) { + if (mounted) { context.showToast(message: "Network Error"); } } else { @@ -125,14 +124,18 @@ class _IllustGalleryPageState extends State { } } - class IllustPage extends StatefulWidget { - const IllustPage(this.illust, {this.favoriteCallback, super.key}); + const IllustPage(this.illust, + {this.favoriteCallback, this.nextPage, this.previousPage, super.key}); final Illust illust; final void Function(bool)? favoriteCallback; + final void Function()? nextPage; + + final void Function()? previousPage; + @override State createState() => _IllustPageState(); } @@ -140,7 +143,7 @@ class IllustPage extends StatefulWidget { class _IllustPageState extends State { @override Widget build(BuildContext context) { - return ColoredBox( + return buildKeyboardListener(ColoredBox( color: FluentTheme.of(context).micaBackgroundColor, child: SizedBox.expand( child: ColoredBox( @@ -166,11 +169,41 @@ class _IllustPageState extends State { }), ), ), + )); + } + + final scrollController = ScrollController(); + + Widget buildKeyboardListener(Widget child) { + return KeyboardListener( + focusNode: FocusNode(), + autofocus: true, + onKeyEvent: (event) { + if (event is! KeyUpEvent) return; + const kShortcutScrollOffset = 200; + if (event.logicalKey == LogicalKeyboardKey.arrowDown) { + scrollController.animateTo( + scrollController.offset + kShortcutScrollOffset, + duration: const Duration(milliseconds: 200), + curve: Curves.easeOut); + } else if (event.logicalKey == LogicalKeyboardKey.arrowUp) { + scrollController.animateTo( + scrollController.offset - kShortcutScrollOffset, + duration: const Duration(milliseconds: 200), + curve: Curves.easeOut); + } else if (event.logicalKey == LogicalKeyboardKey.arrowRight) { + widget.nextPage?.call(); + } else if (event.logicalKey == LogicalKeyboardKey.arrowLeft) { + widget.previousPage?.call(); + } + }, + child: child, ); } Widget buildBody(double width, double height) { return ListView.builder( + controller: scrollController, itemCount: widget.illust.images.length + 2, padding: EdgeInsets.zero, itemBuilder: (context, index) { @@ -180,9 +213,9 @@ class _IllustPageState extends State { void openImage(int index) { var images = []; - for(var i = 0; i < widget.illust.images.length; i++) { + for (var i = 0; i < widget.illust.images.length; i++) { var downloadFile = DownloadManager().getImage(widget.illust.id, i); - if(downloadFile != null) { + if (downloadFile != null) { images.add("file://${downloadFile.path}"); } else { images.add(widget.illust.images[i].original); @@ -200,7 +233,7 @@ class _IllustPageState extends State { } index--; File? downloadFile; - if(widget.illust.downloaded) { + if (widget.illust.downloaded) { downloadFile = DownloadManager().getImage(widget.illust.id, index); } if (index == widget.illust.images.length) { @@ -218,7 +251,7 @@ class _IllustPageState extends State { } Widget image; - if(!widget.illust.isUgoira) { + if (!widget.illust.isUgoira) { image = SizedBox( width: imageWidth, height: imageHeight, @@ -227,7 +260,8 @@ class _IllustPageState extends State { child: Image( key: ValueKey(index), image: downloadFile == null - ? CachedImageProvider(widget.illust.images[index].large) as ImageProvider + ? CachedImageProvider(widget.illust.images[index].large) + as ImageProvider : FileImage(downloadFile) as ImageProvider, width: imageWidth, fit: BoxFit.cover, @@ -235,11 +269,12 @@ class _IllustPageState extends State { loadingBuilder: (context, child, loadingProgress) { if (loadingProgress == null) return child; double? value; - if(loadingProgress.expectedTotalBytes != null) { + if (loadingProgress.expectedTotalBytes != null) { value = (loadingProgress.cumulativeBytesLoaded / - loadingProgress.expectedTotalBytes!)*100; + loadingProgress.expectedTotalBytes!) * + 100; } - if(value != null && (value > 100 || value < 0)) { + if (value != null && (value > 100 || value < 0)) { value = null; } return Center( @@ -251,8 +286,7 @@ class _IllustPageState extends State { ), ), ); - } - ), + }), ), ); } else { @@ -271,7 +305,8 @@ class _IllustPageState extends State { } class _BottomBar extends StatefulWidget { - const _BottomBar(this.illust, this.height, this.width, {this.favoriteCallback}); + const _BottomBar(this.illust, this.height, this.width, + {this.favoriteCallback}); final void Function(bool)? favoriteCallback; @@ -285,7 +320,7 @@ class _BottomBar extends StatefulWidget { State<_BottomBar> createState() => _BottomBarState(); } -class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ +class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin { double pageHeight = 0; double widgetHeight = 48; @@ -299,7 +334,8 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ late final AnimationController animationController; double get minValue => pageHeight - widgetHeight; - double get maxValue => pageHeight - _kBottomBarHeight - context.padding.bottom; + double get maxValue => + pageHeight - _kBottomBarHeight - context.padding.bottom; @override void initState() { @@ -315,9 +351,7 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ ..onEnd = _handlePointerUp ..onCancel = _handlePointerCancel; animationController = AnimationController( - vsync: this, duration: const Duration(milliseconds: 180), - value: 1 - ); + vsync: this, duration: const Duration(milliseconds: 180), value: 1); super.initState(); } @@ -327,16 +361,16 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ final minValue = pageHeight - widgetHeight; final maxValue = pageHeight - _kBottomBarHeight - context.padding.bottom; var top = animationController.value * (maxValue - minValue) + minValue; - top = (top + offset).clamp(minValue, maxValue); + top = (top + offset).clamp(minValue, maxValue); animationController.value = (top - minValue) / (maxValue - minValue); } void _handlePointerUp(DragEndDetails details) { var speed = details.primaryVelocity ?? 0; const minShouldTransitionSpeed = 1000; - if(speed > minShouldTransitionSpeed) { + if (speed > minShouldTransitionSpeed) { animationController.forward(); - } else if(speed < 0 - minShouldTransitionSpeed) { + } else if (speed < 0 - minShouldTransitionSpeed) { animationController.reverse(); } else { _handlePointerCancel(); @@ -344,8 +378,9 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ } void _handlePointerCancel() { - if(animationController.value == 1 || animationController.value == 0) return; - if(animationController.value >= 0.5 ) { + if (animationController.value == 1 || animationController.value == 0) + return; + if (animationController.value >= 0.5) { animationController.forward(); } else { animationController.reverse(); @@ -360,13 +395,13 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ }); } _recognizer.dispose(); - if(_width != widget.width) { + if (_width != widget.width) { _width = widget.width; Future.microtask(() { final box = key.currentContext?.findRenderObject() as RenderBox?; var oldHeight = widgetHeight; widgetHeight = (box?.size.height) ?? 0; - if(oldHeight != widgetHeight) { + if (oldHeight != widgetHeight) { setState(() {}); } }); @@ -392,9 +427,9 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ _recognizer.addPointer(event); }, onPointerSignal: (event) { - if(event is PointerScrollEvent) { + if (event is PointerScrollEvent) { var offset = (event).scrollDelta.dy; - if(offset < 0) { + if (offset < 0) { animationController.reverse(); } else { animationController.forward(); @@ -402,9 +437,10 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ } }, child: Card( - borderRadius: const BorderRadius.vertical(top: Radius.circular(8)), + borderRadius: + const BorderRadius.vertical(top: Radius.circular(8)), backgroundColor: - FluentTheme.of(context).micaBackgroundColor.withOpacity(0.96), + FluentTheme.of(context).micaBackgroundColor.withOpacity(0.96), padding: const EdgeInsets.symmetric(horizontal: 8), child: SizedBox( width: double.infinity, @@ -420,9 +456,11 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ "${"Artwork ID".tl}: ${widget.illust.id}\n" "${"Artist ID".tl}: ${widget.illust.author.id}\n" "${widget.illust.createDate.toString().split('.').first}", - style: TextStyle(color: ColorScheme.of(context).outline),) - .paddingLeft(4), - SizedBox(height: 8 + context.padding.bottom,) + style: TextStyle(color: ColorScheme.of(context).outline), + ).paddingLeft(4), + SizedBox( + height: 8 + context.padding.bottom, + ) ], ), ), @@ -464,15 +502,16 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ bool isFollowing = false; Widget buildAuthor() { - void follow() async{ - if(isFollowing) return; + void follow() async { + if (isFollowing) return; setState(() { isFollowing = true; }); var method = widget.illust.author.isFollowed ? "delete" : "add"; - var res = await Network().follow(widget.illust.author.id.toString(), method); - if(res.error) { - if(mounted) { + var res = + await Network().follow(widget.illust.author.id.toString(), method); + if (res.error) { + if (mounted) { context.showToast(message: "Network Error"); } } else { @@ -502,12 +541,12 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ child: ColoredBox( color: ColorScheme.of(context).secondaryContainer, child: GestureDetector( - onTap: () => context.to(() => - UserInfoPage( + onTap: () => context.to(() => UserInfoPage( widget.illust.author.id.toString(), followCallback: (b) => setState(() { widget.illust.author.isFollowed = b; - }),)), + }), + )), child: AnimatedImage( image: CachedImageProvider(widget.illust.author.avatar), width: 40, @@ -522,24 +561,28 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ const SizedBox( width: 8, ), - if(showUserName) + if (showUserName) Expanded( child: Text( widget.illust.author.name, maxLines: 2, ), ), - if(isFollowing) - Button(onPressed: follow, child: const SizedBox( - width: 42, - height: 24, - child: Center( - child: SizedBox.square( - dimension: 18, - child: ProgressRing(strokeWidth: 2,), - ), - ), - )) + if (isFollowing) + Button( + onPressed: follow, + child: const SizedBox( + width: 42, + height: 24, + child: Center( + child: SizedBox.square( + dimension: 18, + child: ProgressRing( + strokeWidth: 2, + ), + ), + ), + )) else if (!widget.illust.author.isFollowed) Button(onPressed: follow, child: Text("Follow".tl).fixWidth(62)) else @@ -558,15 +601,16 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ bool isBookmarking = false; - void favorite([String type = "public"]) async{ - if(isBookmarking) return; + void favorite([String type = "public"]) async { + if (isBookmarking) return; setState(() { isBookmarking = true; }); var method = widget.illust.isBookmarked ? "delete" : "add"; - var res = await Network().addBookmark(widget.illust.id.toString(), method, type); - if(res.error) { - if(mounted) { + var res = + await Network().addBookmark(widget.illust.id.toString(), method, type); + if (res.error) { + if (mounted) { context.showToast(message: "Network Error"); } } else { @@ -579,7 +623,9 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ } Iterable buildActions(double width) sync* { - yield const SizedBox(width: 8,); + yield const SizedBox( + width: 8, + ); void download() { DownloadManager().addDownloadingTask(widget.illust); @@ -594,13 +640,15 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ height: 28, child: Row( children: [ - if(isBookmarking) + if (isBookmarking) const SizedBox( width: 18, height: 18, - child: ProgressRing(strokeWidth: 2,), + child: ProgressRing( + strokeWidth: 2, + ), ) - else if(widget.illust.isBookmarked) + else if (widget.illust.isBookmarked) Icon( Icons.favorite, color: ColorScheme.of(context).error, @@ -611,10 +659,12 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ Icons.favorite_border, size: 18, ), - if(showText) - const SizedBox(width: 8,), - if(showText) - if(widget.illust.isBookmarked) + if (showText) + const SizedBox( + width: 8, + ), + if (showText) + if (widget.illust.isBookmarked) Text("Cancel".tl) else Text("Favorite".tl) @@ -623,10 +673,12 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ ), ); - yield const SizedBox(width: 8,); + yield const SizedBox( + width: 8, + ); if (!widget.illust.downloaded) { - if(widget.illust.downloading) { + if (widget.illust.downloading) { yield Button( onPressed: () => {}, child: SizedBox( @@ -638,11 +690,15 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ color: ColorScheme.of(context).outline, size: 18, ), - if(showText) - const SizedBox(width: 8,), - if(showText) - Text("Downloading".tl, - style: TextStyle(color: ColorScheme.of(context).outline),), + if (showText) + const SizedBox( + width: 8, + ), + if (showText) + Text( + "Downloading".tl, + style: TextStyle(color: ColorScheme.of(context).outline), + ), ], ), ), @@ -658,10 +714,11 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ FluentIcons.download, size: 18, ), - if(showText) - const SizedBox(width: 8,), - if(showText) - Text("Download".tl), + if (showText) + const SizedBox( + width: 8, + ), + if (showText) Text("Download".tl), ], ), ), @@ -669,7 +726,9 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ } } - yield const SizedBox(width: 8,); + yield const SizedBox( + width: 8, + ); yield Button( onPressed: () => CommentsPage.show(context, widget.illust.id.toString()), @@ -681,68 +740,105 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ FluentIcons.comment, size: 18, ), - if(showText) - const SizedBox(width: 8,), - if(showText) - Text("Comment".tl), + if (showText) + const SizedBox( + width: 8, + ), + if (showText) Text("Comment".tl), ], ), ), ); } - Widget buildStats(){ + Widget buildStats() { return SizedBox( height: 56, child: Row( children: [ - const SizedBox(width: 2,), + const SizedBox( + width: 2, + ), Expanded( child: Container( height: 52, decoration: BoxDecoration( - border: Border.all(color: ColorScheme.of(context).outlineVariant, width: 0.6), - borderRadius: BorderRadius.circular(4) - ), + border: Border.all( + color: ColorScheme.of(context).outlineVariant, + width: 0.6), + borderRadius: BorderRadius.circular(4)), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), child: Row( children: [ Column( mainAxisSize: MainAxisSize.min, children: [ - const Icon(FluentIcons.view, size: 20,), - Text("Views".tl, style: const TextStyle(fontSize: 12),) + const Icon( + FluentIcons.view, + size: 20, + ), + Text( + "Views".tl, + style: const TextStyle(fontSize: 12), + ) ], ), - const SizedBox(width: 12,), - Text(widget.illust.totalView.toString(), style: TextStyle(color: ColorScheme.of(context).primary, fontWeight: FontWeight.w500, fontSize: 18),) + const SizedBox( + width: 12, + ), + Text( + widget.illust.totalView.toString(), + style: TextStyle( + color: ColorScheme.of(context).primary, + fontWeight: FontWeight.w500, + fontSize: 18), + ) ], ), ), ), - const SizedBox(width: 16,), - Expanded(child: Container( + const SizedBox( + width: 16, + ), + Expanded( + child: Container( height: 52, decoration: BoxDecoration( - border: Border.all(color: ColorScheme.of(context).outlineVariant, width: 0.6), - borderRadius: BorderRadius.circular(4) - ), + border: Border.all( + color: ColorScheme.of(context).outlineVariant, width: 0.6), + borderRadius: BorderRadius.circular(4)), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), child: Row( children: [ Column( mainAxisSize: MainAxisSize.min, children: [ - const Icon(FluentIcons.six_point_star, size: 20,), - Text("Favorites".tl, style: const TextStyle(fontSize: 12),) + const Icon( + FluentIcons.six_point_star, + size: 20, + ), + Text( + "Favorites".tl, + style: const TextStyle(fontSize: 12), + ) ], ), - const SizedBox(width: 12,), - Text(widget.illust.totalBookmarks.toString(), style: TextStyle(color: ColorScheme.of(context).primary, fontWeight: FontWeight.w500, fontSize: 18),) + const SizedBox( + width: 12, + ), + Text( + widget.illust.totalBookmarks.toString(), + style: TextStyle( + color: ColorScheme.of(context).primary, + fontWeight: FontWeight.w500, + fontSize: 18), + ) ], ), )), - const SizedBox(width: 2,), + const SizedBox( + width: 2, + ), ], ), ); @@ -756,7 +852,7 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ runSpacing: 4, children: widget.illust.tags.map((e) { var text = e.name; - if(e.translatedName != null && e.name != e.translatedName) { + if (e.translatedName != null && e.name != e.translatedName) { text += "/${e.translatedName}"; } return MouseRegion( @@ -767,7 +863,10 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ }, child: Card( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6), - child: Text(text, style: const TextStyle(fontSize: 13),), + child: Text( + text, + style: const TextStyle(fontSize: 13), + ), ), ), ); @@ -785,13 +884,15 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ height: 28, child: Row( children: [ - if(isBookmarking) + if (isBookmarking) const SizedBox( width: 18, height: 18, - child: ProgressRing(strokeWidth: 2,), + child: ProgressRing( + strokeWidth: 2, + ), ) - else if(widget.illust.isBookmarked) + else if (widget.illust.isBookmarked) Icon( Icons.favorite, color: ColorScheme.of(context).error, @@ -802,32 +903,44 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ Icons.favorite_border, size: 18, ), - const SizedBox(width: 8,), - if(widget.illust.isBookmarked) - Text("Cancel".tl) - else - Text("Private".tl) + const SizedBox( + width: 8, + ), + if (widget.illust.isBookmarked) + Text("Cancel".tl) + else + Text("Private".tl) ], ), ), ), - const SizedBox(width: 6,), + const SizedBox( + width: 6, + ), Button( onPressed: () { - Share.share("${widget.illust.title}\nhttps://pixiv.net/artworks/${widget.illust.id}"); + Share.share( + "${widget.illust.title}\nhttps://pixiv.net/artworks/${widget.illust.id}"); }, child: SizedBox( height: 28, child: Row( children: [ - const Icon(Icons.share, size: 18,), - const SizedBox(width: 8,), + const Icon( + Icons.share, + size: 18, + ), + const SizedBox( + width: 8, + ), Text("Share".tl) ], ), ), ), - const SizedBox(width: 6,), + const SizedBox( + width: 6, + ), Button( onPressed: () { var text = "https://pixiv.net/artworks/${widget.illust.id}"; @@ -839,13 +952,17 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ child: Row( children: [ const Icon(Icons.copy, size: 18), - const SizedBox(width: 8,), + const SizedBox( + width: 8, + ), Text("Link".tl) ], ), ), ), - const SizedBox(width: 6,), + const SizedBox( + width: 6, + ), Button( onPressed: () { context.to(() => _RelatedIllustsPage(widget.illust.id.toString())); @@ -855,7 +972,9 @@ class _BottomBarState extends State<_BottomBar> with TickerProviderStateMixin{ child: Row( children: [ const Icon(Icons.stars, size: 18), - const SizedBox(width: 8,), + const SizedBox( + width: 8, + ), Text("Related".tl) ], ), @@ -896,7 +1015,8 @@ class _RelatedIllustsPage extends StatefulWidget { State<_RelatedIllustsPage> createState() => _RelatedIllustsPageState(); } -class _RelatedIllustsPageState extends MultiPageLoadingState<_RelatedIllustsPage, Illust> { +class _RelatedIllustsPageState + extends MultiPageLoadingState<_RelatedIllustsPage, Illust> { @override Widget? buildFrame(BuildContext context, Widget child) { return Column( @@ -911,16 +1031,16 @@ class _RelatedIllustsPageState extends MultiPageLoadingState<_RelatedIllustsPage @override Widget buildContent(BuildContext context, final List data) { - return LayoutBuilder(builder: (context, constrains){ + return LayoutBuilder(builder: (context, constrains) { return MasonryGridView.builder( - padding: const EdgeInsets.symmetric(horizontal: 8) - + EdgeInsets.only(bottom: context.padding.bottom), + padding: const EdgeInsets.symmetric(horizontal: 8) + + EdgeInsets.only(bottom: context.padding.bottom), gridDelegate: const SliverSimpleGridDelegateWithMaxCrossAxisExtent( maxCrossAxisExtent: 240, ), itemCount: data.length, itemBuilder: (context, index) { - if(index == data.length - 1){ + if (index == data.length - 1) { nextPage(); } return IllustWidget(data[index]); @@ -932,18 +1052,17 @@ class _RelatedIllustsPageState extends MultiPageLoadingState<_RelatedIllustsPage String? nextUrl; @override - Future>> loadData(page) async{ - if(nextUrl == "end") { + Future>> loadData(page) async { + if (nextUrl == "end") { return Res.error("No more data"); } var res = nextUrl == null ? await Network().relatedIllusts(widget.id) : await Network().getIllustsWithNextUrl(nextUrl!); - if(!res.error) { + if (!res.error) { nextUrl = res.subData; nextUrl ??= "end"; } return res; } } -