From c32b98fa7fc5fd44568cf7ffb118dceb069f3521 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sun, 2 Mar 2025 11:47:06 +0800 Subject: [PATCH] fix: thumbnail image url Closes #360 Signed-off-by: bggRGjQaUbCoE --- lib/common/widgets/html_render.dart | 6 ----- .../interactiveviewer_gallery.dart | 11 ++++---- lib/common/widgets/network_img_layer.dart | 15 ++--------- lib/utils/extension.dart | 7 ++++-- lib/utils/utils.dart | 25 +++++++++++++++++++ 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/lib/common/widgets/html_render.dart b/lib/common/widgets/html_render.dart index 68fd1d79..3e016f76 100644 --- a/lib/common/widgets/html_render.dart +++ b/lib/common/widgets/html_render.dart @@ -28,12 +28,6 @@ Widget htmlRender({ String imgUrl = key.contains('src') ? attributes['src'] as String : attributes['data-src'] as String; - if (imgUrl.startsWith('//')) { - imgUrl = 'https:$imgUrl'; - } - if (imgUrl.startsWith('http://')) { - imgUrl = imgUrl.replaceAll('http://', 'https://'); - } imgUrl = imgUrl.contains('@') ? imgUrl.split('@').first : imgUrl; final bool isEmote = imgUrl.contains('/emote/'); final bool isMall = imgUrl.contains('/mall/'); diff --git a/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart b/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart index 04d8157d..19836e3f 100644 --- a/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart +++ b/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart @@ -112,15 +112,12 @@ class _InteractiveviewerGalleryState extends State late final RxInt currentIndex = widget.initIndex.obs; - late List _thumbList; late final int _quality = GStorage.previewQ; @override void initState() { super.initState(); - _thumbList = List.generate(widget.sources.length, (_) => true); - _pageController = PageController(initialPage: widget.initIndex); _transformationController = custom.TransformationController(); @@ -263,9 +260,11 @@ class _InteractiveviewerGalleryState extends State } } - String _getActualUrl(int index) => _thumbList[index] && _quality != 100 - ? '${widget.sources[index].url}@${_quality}q.webp'.http2https - : widget.sources[index].url.http2https; + String _getActualUrl(int index) { + return _quality != 100 + ? Utils.thumbnailImgUrl(widget.sources[index].url) + : widget.sources[index].url.http2https; + } void onClose() { if (widget.onClose != null) { diff --git a/lib/common/widgets/network_img_layer.dart b/lib/common/widgets/network_img_layer.dart index 387558ac..7637cffc 100644 --- a/lib/common/widgets/network_img_layer.dart +++ b/lib/common/widgets/network_img_layer.dart @@ -1,7 +1,7 @@ +import 'package:PiliPlus/utils/utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:PiliPlus/utils/extension.dart'; -import 'package:PiliPlus/utils/global_data.dart'; import '../constants.dart'; class NetworkImgLayer extends StatelessWidget { @@ -56,8 +56,6 @@ class NetworkImgLayer extends StatelessWidget { } Widget _buildImage(context) { - late final int defaultImgQuality = GlobalData().imgQuality; - bool thumbnail = true; int? memCacheWidth, memCacheHeight; if (callback?.call() == true || width <= height) { memCacheWidth = width.cacheSize(context); @@ -65,8 +63,7 @@ class NetworkImgLayer extends StatelessWidget { memCacheHeight = height.cacheSize(context); } return CachedNetworkImage( - imageUrl: - '${src?.startsWith('//') == true ? 'https:$src' : src?.http2https}${type != 'emote' && type != 'cover' && thumbnail ? '@${quality ?? defaultImgQuality}q.webp' : ''}', + imageUrl: Utils.thumbnailImgUrl(src, quality), width: width, height: ignoreHeight == null || ignoreHeight == false ? height : null, memCacheWidth: memCacheWidth, @@ -77,17 +74,9 @@ class NetworkImgLayer extends StatelessWidget { fadeOutDuration: fadeOutDuration ?? const Duration(milliseconds: 120), fadeInDuration: fadeInDuration ?? const Duration(milliseconds: 120), filterQuality: FilterQuality.low, - // errorWidget: (BuildContext context, String url, Object error) => - // placeholder(context), placeholder: (BuildContext context, String url) => getPlaceHolder?.call() ?? placeholder(context), imageBuilder: imageBuilder, - // errorListener: (value) { - // thumbnail = false; - // if (context.mounted) { - // (context as Element).markNeedsBuild(); - // } - // }, ); } diff --git a/lib/utils/extension.dart b/lib/utils/extension.dart index 1201dcda..eb0def5f 100644 --- a/lib/utils/extension.dart +++ b/lib/utils/extension.dart @@ -52,8 +52,11 @@ extension ListExt on List? { bool ne(List? other) => !eq(other); } -extension StringExt on String { - String get http2https => replaceFirst(RegExp("^http://"), "https://"); +final _regExp = RegExp("^(http:)?//", caseSensitive: false); + +extension StringExt on String? { + String get http2https => + this == null ? '' : this!.replaceFirst(_regExp, "https://"); } extension StringNullExt on String? { diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 50f8f56f..3dba1583 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -26,6 +26,7 @@ import 'package:PiliPlus/pages/video/detail/introduction/widgets/group_panel.dar import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/feed_back.dart'; +import 'package:PiliPlus/utils/global_data.dart'; import 'package:PiliPlus/utils/id_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/url_utils.dart'; @@ -49,6 +50,30 @@ class Utils { static const channel = MethodChannel("PiliPlus"); + static final regExp = + RegExp(r'(@(\d+[a-z]_?)*)(\..*)?$', caseSensitive: false); + + static String thumbnailImgUrl(String? src, [int? quality]) { + if (src != null) { + bool hasMatch = false; + src = src.splitMapJoin( + regExp, + onMatch: (Match match) { + hasMatch = true; + String suffix = match.group(3) ?? '.webp'; + return '${match.group(1)}_${quality ?? GlobalData().imgQuality}q$suffix'; + }, + onNonMatch: (String str) { + return str; + }, + ); + if (hasMatch.not) { + src += '@${quality ?? GlobalData().imgQuality}q.webp'; + } + } + return src.http2https; + } + static bool? _isIpad; static Future isIpad() async {