chatapp3-flutter/lib/shared/tools/sc_network_image_utils.dart
2026-04-15 11:44:49 +08:00

86 lines
2.5 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/painting.dart';
import 'package:yumi/app/constants/sc_global_config.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
bool _requiresAuthenticatedImageHeaders(String url) {
return url.contains("/external/oss/local/");
}
Map<String, String>? buildNetworkImageHeaders(String url) {
if (!_requiresAuthenticatedImageHeaders(url)) {
return null;
}
final uri = Uri.tryParse(url);
final headers = <String, String>{
"req-lang": SCGlobalConfig.lang,
"X-Forwarded-Proto": "http",
"User-Agent": "Dart/3.7.2(dart:io)",
"req-imei": SCGlobalConfig.imei,
"req-app-intel":
"version=${SCGlobalConfig.version};build=${SCGlobalConfig.build};model=${SCGlobalConfig.model};sysVersion=${SCGlobalConfig.sysVersion};channel=${SCGlobalConfig.channel}",
"req-client": Platform.isAndroid ? "Android" : "iOS",
"req-sys-origin":
"origin=${SCGlobalConfig.origin};originChild=${SCGlobalConfig.originChild}",
};
if ((uri?.host ?? "").isNotEmpty) {
headers["Host"] = uri!.host;
}
final token = AccountStorage().getToken();
if (token.isNotEmpty) {
headers["Authorization"] = "Bearer $token";
}
headers.removeWhere((key, value) => value.trim().isEmpty);
return headers;
}
ImageProvider<Object> buildCachedImageProvider(String url) {
if (url.startsWith("http")) {
return ExtendedNetworkImageProvider(
url,
headers: buildNetworkImageHeaders(url),
cache: true,
cacheMaxAge: const Duration(days: 7),
);
}
return FileImage(File(url));
}
Future<bool> warmNetworkImage(
String url, {
Duration timeout = const Duration(seconds: 6),
}) async {
if (url.isEmpty) {
return false;
}
final provider = buildCachedImageProvider(url);
final stream = provider.resolve(ImageConfiguration.empty);
final completer = Completer<bool>();
late final ImageStreamListener listener;
listener = ImageStreamListener(
(image, synchronousCall) {
if (!completer.isCompleted) {
completer.complete(true);
}
stream.removeListener(listener);
},
onError: (Object error, StackTrace? stackTrace) {
if (!completer.isCompleted) {
completer.complete(false);
}
stream.removeListener(listener);
},
);
stream.addListener(listener);
return completer.future.timeout(
timeout,
onTimeout: () {
stream.removeListener(listener);
return false;
},
);
}