drop gif emote, static thumbnail gif

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-04-26 14:11:37 +08:00
parent 877bdf64b4
commit 7d1b393511
16 changed files with 61 additions and 26 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

BIN
assets/images/live/live.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -15,9 +15,9 @@ abstract final class Assets {
static const trendingBanner = 'assets/images/trending_banner.png'; static const trendingBanner = 'assets/images/trending_banner.png';
static const ai = 'assets/images/ai.png'; static const ai = 'assets/images/ai.png';
static const livingChart = 'assets/images/live.gif'; // static const livingChart = 'assets/images/live.gif';
static const livingStatic = 'assets/images/live.png'; static const livingStatic = 'assets/images/live.png';
static const livingRect = 'assets/images/live/live.gif'; static const livingRect = 'assets/images/live/live.png';
static const livingBackground = 'assets/images/live/default_bg.webp'; static const livingBackground = 'assets/images/live/default_bg.webp';
static const thunder1 = 'assets/images/paycoins/ic_thunder_1.png'; static const thunder1 = 'assets/images/paycoins/ic_thunder_1.png';

View File

@@ -71,7 +71,15 @@ class NetworkImgLayer extends StatelessWidget {
memCacheHeight = height.cacheSize(context); memCacheHeight = height.cacheSize(context);
} }
return CachedNetworkImage( return CachedNetworkImage(
imageUrl: ImageUtils.thumbnailUrl(src, quality), imageUrl: ImageUtils.thumbnailUrl(
src,
maxQuality: quality,
/// remove gif
suffix: src!.endsWith(ImageUtils.kSuffixGIF)
? ImageUtils.kSuffixJPG
: ImageUtils.kSuffixWEBP,
),
width: width, width: width,
height: height, height: height,
memCacheWidth: memCacheWidth, memCacheWidth: memCacheWidth,

View File

@@ -22,7 +22,6 @@ import 'package:PiliPlus/common/style.dart';
import 'package:PiliPlus/common/widgets/badge.dart'; import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_grid/image_grid_builder.dart'; import 'package:PiliPlus/common/widgets/image_grid/image_grid_builder.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart'; import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart'; import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart';
@@ -59,6 +58,8 @@ class ImageModel {
bool get isLivePhoto => bool get isLivePhoto =>
_isLivePhoto ??= enableLivePhoto && liveUrl?.isNotEmpty == true; _isLivePhoto ??= enableLivePhoto && liveUrl?.isNotEmpty == true;
bool get isGif => url.endsWith(ImageUtils.kSuffixGIF);
static bool enableLivePhoto = Pref.enableLivePhoto; static bool enableLivePhoto = Pref.enableLivePhoto;
} }
@@ -245,13 +246,20 @@ class ImageGridView extends StatelessWidget {
text: 'Live', text: 'Live',
right: 8, right: 8,
bottom: 8, bottom: 8,
type: PBadgeType.gray, type: .gray,
) )
else if (item.isLongPic) else if (item.isLongPic)
const PBadge( const PBadge(
text: '长图', text: '长图',
right: 8, right: 8,
bottom: 8, bottom: 8,
)
else if (item.isGif)
const PBadge(
text: 'GIF',
right: 8,
bottom: 8,
type: .gray,
), ),
], ],
); );

View File

@@ -98,7 +98,7 @@ class _GalleryViewerState extends State<GalleryViewer>
String _getActualUrl(String url) { String _getActualUrl(String url) {
return _quality != 100 return _quality != 100
? ImageUtils.thumbnailUrl(url, _quality) ? ImageUtils.thumbnailUrl(url, maxQuality: _quality)
: url.http2https; : url.http2https;
} }
@@ -413,7 +413,10 @@ class _GalleryViewerState extends State<GalleryViewer>
_containerSize.width.cacheSize(context), _containerSize.width.cacheSize(context),
null, null,
CachedNetworkImageProvider( CachedNetworkImageProvider(
ImageUtils.thumbnailUrl(item.url, widget.quality), ImageUtils.thumbnailUrl(
item.url,
maxQuality: widget.quality,
),
), ),
), ),
minScale: widget.minScale, minScale: widget.minScale,

View File

@@ -1173,10 +1173,11 @@ class Emoji {
String? url; String? url;
late num size; late num size;
/// remove gif
Emoji.fromJson(Map<String, dynamic> json) { Emoji.fromJson(Map<String, dynamic> json) {
url = url =
noneNullOrEmptyString(json['webp_url']) ?? // noneNullOrEmptyString(json['webp_url']) ??
noneNullOrEmptyString(json['gif_url']) ?? // noneNullOrEmptyString(json['gif_url']) ??
noneNullOrEmptyString(json['icon_url']); noneNullOrEmptyString(json['icon_url']);
size = json['size'] ?? 1; size = json['size'] ?? 1;
} }

View File

@@ -298,7 +298,7 @@ class _ArticlePageState extends CommonDynPageState<ArticlePage> {
: null, : null,
imageUrl: ImageUtils.thumbnailUrl( imageUrl: ImageUtils.thumbnailUrl(
pic.url, pic.url,
60, maxQuality: 60,
), ),
fadeInDuration: const Duration( fadeInDuration: const Duration(
milliseconds: 120, milliseconds: 120,

View File

@@ -73,7 +73,10 @@ class ArticleOpus extends StatelessWidget {
width: width, width: width,
height: height, height: height,
memCacheWidth: width.cacheSize(context), memCacheWidth: width.cacheSize(context),
imageUrl: ImageUtils.thumbnailUrl(card.url, 60), imageUrl: ImageUtils.thumbnailUrl(
card.url,
maxQuality: 60,
),
placeholder: (_, _) => const SizedBox.shrink(), placeholder: (_, _) => const SizedBox.shrink(),
), ),
), ),

View File

@@ -62,7 +62,7 @@ Widget htmlRender({
width: width, width: width,
height: isEmote ? 22.0 : null, height: isEmote ? 22.0 : null,
memCacheWidth: width.cacheSize(context), memCacheWidth: width.cacheSize(context),
imageUrl: ImageUtils.thumbnailUrl(imgUrl, 60), imageUrl: ImageUtils.thumbnailUrl(imgUrl, maxQuality: 60),
fadeInDuration: const Duration(milliseconds: 120), fadeInDuration: const Duration(milliseconds: 120),
fadeOutDuration: const Duration(milliseconds: 120), fadeOutDuration: const Duration(milliseconds: 120),
placeholder: (context, url) => Image.asset(Assets.loading), placeholder: (context, url) => Image.asset(Assets.loading),

View File

@@ -229,7 +229,7 @@ class OpusContent extends StatelessWidget {
width: width, width: width,
height: height, height: height,
memCacheWidth: width.cacheSize(context), memCacheWidth: width.cacheSize(context),
imageUrl: ImageUtils.thumbnailUrl(pic.url!, 60), imageUrl: ImageUtils.thumbnailUrl(pic.url!, maxQuality: 60),
fadeInDuration: const Duration(milliseconds: 120), fadeInDuration: const Duration(milliseconds: 120),
fadeOutDuration: const Duration(milliseconds: 120), fadeOutDuration: const Duration(milliseconds: 120),
placeholder: (_, _) => Image.asset(Assets.loading), placeholder: (_, _) => Image.asset(Assets.loading),

View File

@@ -293,7 +293,7 @@ class _AudioPageState extends State<AudioPage> {
WidgetSpan( WidgetSpan(
alignment: .bottom, alignment: .bottom,
child: Image.asset( child: Image.asset(
Assets.livingChart, Assets.livingStatic,
width: 16, width: 16,
height: 16, height: 16,
cacheWidth: 16.cacheSize( cacheWidth: 16.cacheSize(
@@ -337,7 +337,7 @@ class _AudioPageState extends State<AudioPage> {
WidgetSpan( WidgetSpan(
alignment: .bottom, alignment: .bottom,
child: Image.asset( child: Image.asset(
Assets.livingChart, Assets.livingStatic,
width: 16, width: 16,
height: 16, height: 16,
cacheWidth: 16.cacheSize( cacheWidth: 16.cacheSize(

View File

@@ -107,7 +107,7 @@ class MedalWall extends StatelessWidget {
Padding( Padding(
padding: const .only(left: 4), padding: const .only(left: 4),
child: Image.asset( child: Image.asset(
Assets.livingChart, Assets.livingStatic,
height: 16, height: 16,
cacheHeight: 16.cacheSize(context), cacheHeight: 16.cacheSize(context),
color: colorScheme.primary, color: colorScheme.primary,

View File

@@ -794,11 +794,13 @@ class ReplyItemGrpc extends StatelessWidget {
spanChildren.add( spanChildren.add(
WidgetSpan( WidgetSpan(
child: NetworkImgLayer( child: NetworkImgLayer(
src: emote.hasWebpUrl() /// remove gif
? emote.webpUrl src: emote.url,
: emote.hasGifUrl() // src: emote.hasWebpUrl()
? emote.gifUrl // ? emote.webpUrl
: emote.url, // : emote.hasGifUrl()
// ? emote.gifUrl
// : emote.url,
type: ImageType.emote, type: ImageType.emote,
width: size, width: size,
height: size, height: size,

View File

@@ -671,7 +671,9 @@ class ChatItem extends StatelessWidget {
if (eInfos != null) { if (eInfos != null) {
for (final e in eInfos!) { for (final e in eInfos!) {
emojiMap[e.text] ??= { emojiMap[e.text] ??= {
'url': e.hasGifUrl() ? e.gifUrl : e.url, /// remove gif
'url': e.url,
// 'url': e.hasGifUrl() ? e.gifUrl : e.url,
'size': e.size * 22.0, 'size': e.size * 22.0,
}; };
} }

View File

@@ -266,7 +266,16 @@ abstract final class ImageUtils {
r'(@(\d+[a-z]_?)*)(\..*)?$', r'(@(\d+[a-z]_?)*)(\..*)?$',
caseSensitive: false, caseSensitive: false,
); );
static String thumbnailUrl(String? src, [int maxQuality = 1]) {
static const kSuffixJPG = '.jpg';
static const kSuffixGIF = '.gif';
static const kSuffixWEBP = '.webp';
static String thumbnailUrl(
String? src, {
int maxQuality = 1,
String suffix = kSuffixWEBP,
}) {
if (src != null && maxQuality != 100) { if (src != null && maxQuality != 100) {
maxQuality = math.max(maxQuality, GlobalData().imgQuality); maxQuality = math.max(maxQuality, GlobalData().imgQuality);
bool hasMatch = false; bool hasMatch = false;
@@ -274,15 +283,14 @@ abstract final class ImageUtils {
_thumbRegex, _thumbRegex,
onMatch: (match) { onMatch: (match) {
hasMatch = true; hasMatch = true;
String suffix = match.group(3) ?? '.webp'; return '${match.group(1)}_${maxQuality}q${match.group(3) ?? suffix}';
return '${match.group(1)}_${maxQuality}q$suffix';
}, },
onNonMatch: (String str) { onNonMatch: (String str) {
return str; return str;
}, },
); );
if (!hasMatch) { if (!hasMatch) {
src += '@${maxQuality}q.webp'; src += '@${maxQuality}q$suffix';
} }
} }
return src.http2https; return src.http2https;