mirror of
https://github.com/nostrlabs-io/zap-stream-flutter.git
synced 2025-06-16 11:58:50 +00:00
refactor: use ProxyImg widget
This commit is contained in:
@ -1,7 +1,10 @@
|
||||
import 'dart:convert';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:convert/convert.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:zap_stream_flutter/theme.dart';
|
||||
|
||||
class ImgProxySettings {
|
||||
final String url;
|
||||
@ -12,11 +15,12 @@ class ImgProxySettings {
|
||||
|
||||
static ImgProxySettings static() {
|
||||
return ImgProxySettings(
|
||||
url: "https://imgproxy.v0l.io",
|
||||
key:
|
||||
"a82fcf26aa0ccb55dfc6b4bd6a1c90744d3be0f38429f21a8828b43449ce7cebe6bdc2b09a827311bef37b18ce35cb1e6b1c60387a254541afa9e5b4264ae942",
|
||||
salt:
|
||||
"a897770d9abf163de055e9617891214e75a9016d748f8ef865e6ffbcb9ed932295659549773a22a019a5f06d0b440c320be411e3fddfe784e199e4f03d74bd9b");
|
||||
url: "https://imgproxy.v0l.io",
|
||||
key:
|
||||
"a82fcf26aa0ccb55dfc6b4bd6a1c90744d3be0f38429f21a8828b43449ce7cebe6bdc2b09a827311bef37b18ce35cb1e6b1c60387a254541afa9e5b4264ae942",
|
||||
salt:
|
||||
"a897770d9abf163de055e9617891214e75a9016d748f8ef865e6ffbcb9ed932295659549773a22a019a5f06d0b440c320be411e3fddfe784e199e4f03d74bd9b",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,8 +39,14 @@ String signUrl(String u, ImgProxySettings settings) {
|
||||
return urlSafe(base64.encode(result.bytes));
|
||||
}
|
||||
|
||||
String proxyImg(BuildContext context, String url,
|
||||
{ImgProxySettings? settings, int? resize, String? sha256, double? dpr}) {
|
||||
String proxyImg(
|
||||
BuildContext context,
|
||||
String url, {
|
||||
ImgProxySettings? settings,
|
||||
int? resize,
|
||||
String? sha256,
|
||||
double? dpr,
|
||||
}) {
|
||||
final s = settings ?? ImgProxySettings.static();
|
||||
|
||||
if (url.startsWith("data:") || url.startsWith("blob:") || url.isEmpty) {
|
||||
@ -63,4 +73,45 @@ String proxyImg(BuildContext context, String url,
|
||||
final sig = signUrl(path, s);
|
||||
|
||||
return '${s.url}/$sig$path';
|
||||
}
|
||||
}
|
||||
|
||||
class ProxyImg extends StatelessWidget {
|
||||
final String? url;
|
||||
|
||||
/// Size of the placeholder & error images
|
||||
final double? placeholderSize;
|
||||
|
||||
/// request imgproxy to resize the image
|
||||
final int? resize;
|
||||
|
||||
final double? width;
|
||||
final double? height;
|
||||
|
||||
const ProxyImg({
|
||||
super.key,
|
||||
required this.url,
|
||||
this.placeholderSize,
|
||||
this.resize,
|
||||
this.width,
|
||||
this.height,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, url ?? "", resize: resize),
|
||||
width: width,
|
||||
height: height,
|
||||
fit: BoxFit.cover,
|
||||
placeholder:
|
||||
(ctx, url) =>
|
||||
SvgPicture.asset("assets/svg/logo.svg", height: placeholderSize),
|
||||
errorWidget:
|
||||
(context, url, error) => SvgPicture.asset(
|
||||
"assets/svg/logo.svg",
|
||||
height: placeholderSize,
|
||||
colorFilter: ColorFilter.mode(WARNING, BlendMode.srcATop),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -44,10 +44,7 @@ class CategoryPage extends StatelessWidget {
|
||||
info!.coverImage!,
|
||||
fit: BoxFit.contain,
|
||||
)
|
||||
: CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, info!.coverImage!),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
: ProxyImg(url: info!.coverImage!),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
|
@ -36,10 +36,7 @@ class ProfilePage extends StatelessWidget {
|
||||
SizedBox(
|
||||
height: 140,
|
||||
width: double.maxFinite,
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, profile.banner!),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
child: ProxyImg(url: profile.banner!),
|
||||
),
|
||||
Row(
|
||||
spacing: 8,
|
||||
|
@ -53,9 +53,7 @@ class _StreamPage extends State<StreamPage> {
|
||||
autoPlay: true,
|
||||
placeholder:
|
||||
(widget.stream.info.image?.isNotEmpty ?? false)
|
||||
? CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, widget.stream.info.image!),
|
||||
)
|
||||
? ProxyImg(url: widget.stream.info.image!)
|
||||
: null,
|
||||
);
|
||||
});
|
||||
@ -109,9 +107,7 @@ class _StreamPage extends State<StreamPage> {
|
||||
color: LAYER_1,
|
||||
child:
|
||||
(stream.info.image?.isNotEmpty ?? false)
|
||||
? CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, stream.info.image!),
|
||||
)
|
||||
? ProxyImg(url: stream.info.image!)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
|
@ -23,17 +23,13 @@ class AvatarWidget extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final thisSize = size ?? 40;
|
||||
return ClipOval(
|
||||
child: CachedNetworkImage(
|
||||
fit: BoxFit.cover,
|
||||
imageUrl: proxyImg(
|
||||
context,
|
||||
profile.picture ??
|
||||
"https://nostr.api.v0l.io/api/v1/avatar/cyberpunks/${profile.pubKey}",
|
||||
resize: thisSize.ceil(),
|
||||
),
|
||||
height: thisSize,
|
||||
child: ProxyImg(
|
||||
url:
|
||||
profile.picture ??
|
||||
"https://nostr.api.v0l.io/api/v1/avatar/cyberpunks/${profile.pubKey}",
|
||||
resize: thisSize.ceil(),
|
||||
width: thisSize,
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
height: thisSize,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:zap_stream_flutter/imgproxy.dart';
|
||||
@ -27,11 +26,7 @@ class CustomEmoji extends StatelessWidget {
|
||||
(t) => t[0] == "emoji" && t[1] == cleanedEmojiName,
|
||||
)?[2];
|
||||
if (customEmoji != null) {
|
||||
return CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, customEmoji),
|
||||
height: size ?? 16,
|
||||
width: size ?? 16,
|
||||
);
|
||||
return ProxyImg(url: customEmoji, width: size ?? 16, height: size ?? 16);
|
||||
} else {
|
||||
return Text(emoji);
|
||||
}
|
||||
|
@ -77,16 +77,9 @@ class StreamCardsWidget extends StatelessWidget {
|
||||
onTap: () {
|
||||
launchUrl(Uri.parse(link));
|
||||
},
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, image!),
|
||||
errorWidget:
|
||||
(_, _, _) => SvgPicture.asset(
|
||||
"assets/svg/logo.svg",
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
child: ProxyImg(url: link, placeholderSize: 40),
|
||||
)
|
||||
: CachedNetworkImage(imageUrl: proxyImg(context, image!)),
|
||||
: ProxyImg(url: link, placeholderSize: 40),
|
||||
),
|
||||
MarkdownBody(
|
||||
data: card.content,
|
||||
|
@ -31,22 +31,7 @@ class StreamTileWidget extends StatelessWidget {
|
||||
aspectRatio: 16 / 9,
|
||||
child: Stack(
|
||||
children: [
|
||||
Center(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: proxyImg(context, stream.info.image ?? ""),
|
||||
fit: BoxFit.cover,
|
||||
placeholder:
|
||||
(ctx, url) => SvgPicture.asset(
|
||||
"assets/svg/logo.svg",
|
||||
height: 100,
|
||||
),
|
||||
errorWidget:
|
||||
(context, url, error) => SvgPicture.asset(
|
||||
"assets/svg/logo.svg",
|
||||
height: 100,
|
||||
),
|
||||
),
|
||||
),
|
||||
Center(child: ProxyImg(url: stream.info.image ?? "", placeholderSize: 100,)),
|
||||
if (stream.info.status != null)
|
||||
Positioned(
|
||||
right: 8,
|
||||
|
Reference in New Issue
Block a user