86 lines
2.5 KiB
Dart
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;
|
|
},
|
|
);
|
|
}
|