Files
Flutter_Shell/lib/config/app_config.dart

216 lines
5.6 KiB
Dart

import 'package:openim_common/openim_common.dart' as openim_common;
enum Environment {
production,
}
class H5Line {
const H5Line({
required this.label,
required this.url,
});
final String label;
final String url;
Uri get uri => Uri.parse(url);
String get displayAddress {
final parsed = uri;
final host = parsed.hasPort ? '${parsed.host}:${parsed.port}' : parsed.host;
final path = parsed.path.isEmpty || parsed.path == '/' ? '' : parsed.path;
return '$host$path';
}
}
class AppConfig {
static const Environment currentEnvironment = Environment.production;
static const String appName = '本地打包';
static const String appLogo = '';
static const String canonicalWebHost = 'h5-test.imharry.work';
static const String _dartDefinedH5LineUrls =
String.fromEnvironment('H5_LINE_URLS');
static const Set<String> legacyWebHosts = {
'h5-test.imharry.work',
};
static final Map<Environment, List<String>> _environmentHosts = {
Environment.production: [
canonicalWebHost,
],
};
static List<String> get environmentHosts {
final generatedHosts = _normalizedUniqueUrls(
openim_common.Config.environmentHosts,
);
if (generatedHosts.isNotEmpty) {
return generatedHosts;
}
return _normalizedUniqueUrls(_environmentHosts[currentEnvironment] ?? []);
}
static List<H5Line> get h5Lines {
final configuredUrls = _dartDefinedH5LineUrls.trim().isEmpty
? environmentHosts
: _normalizedUniqueUrls(_dartDefinedH5LineUrls.split(','));
final urls = configuredUrls.isEmpty
? _normalizedUniqueUrls(const [canonicalWebHost])
: configuredUrls;
return [
for (var index = 0; index < urls.length; index += 1)
H5Line(label: '线路${index + 1}', url: urls[index]),
];
}
static String homeUrl({int lineIndex = 0, String? appName, String? appLogo}) {
final lines = h5Lines;
final safeIndex = _safeLineIndex(lineIndex, lines.length);
return lines[safeIndex].url;
}
static String withFreshShellParams(String url) {
return _removeShellParams(Uri.parse(url)).toString();
}
static bool shouldRewriteMainFrameUrl(String url) {
return false;
}
static String canonicalizeMainFrameUrl(String url) {
return url;
}
static bool isLoginPageUrl(String? url) {
if (url == null || url.isEmpty) {
return false;
}
final uri = Uri.tryParse(url);
if (uri == null) {
return false;
}
return _isLoginPath(uri.path) || _isLoginPath(uri.fragment);
}
static int? lineIndexForUrl(String url) {
final uri = Uri.tryParse(url);
if (uri == null) {
return null;
}
final lines = h5Lines;
for (var index = 0; index < lines.length; index += 1) {
if (_isSameLine(lines[index].uri, uri)) {
return index;
}
}
return null;
}
static Uri _removeShellParams(Uri uri) {
final queryParameters = Map<String, String>.from(uri.queryParameters);
queryParameters.remove('flutter_shell');
queryParameters.remove('shell_cache_bust');
queryParameters.remove('shell_app_name');
queryParameters.remove('shell_app_logo');
final fragmentParameters = Uri.splitQueryString(uri.fragment);
fragmentParameters.remove('shell_app_name');
fragmentParameters.remove('shell_app_logo');
return uri.replace(
queryParameters: queryParameters,
fragment: fragmentParameters.isEmpty
? ''
: Uri(queryParameters: fragmentParameters).query,
);
}
static int _safeLineIndex(int index, int length) {
if (length <= 0 || index < 0 || index >= length) {
return 0;
}
return index;
}
static bool _isLoginPath(String path) {
final normalized = path.trim();
if (normalized.isEmpty) {
return false;
}
final pathOnly = normalized.split('?').first.split('#').first;
final segments = pathOnly.split('/').where((segment) => segment.isNotEmpty);
if (segments.isEmpty) {
return false;
}
return segments.last == 'login';
}
static bool _isSameLine(Uri lineUri, Uri uri) {
if (lineUri.host.toLowerCase() != uri.host.toLowerCase()) {
return false;
}
if (lineUri.hasPort && lineUri.port != uri.port) {
return false;
}
if (lineUri.scheme.isNotEmpty && lineUri.scheme != uri.scheme) {
return false;
}
final linePath = _pathWithTrailingSlash(lineUri.path);
final uriPath = _pathWithTrailingSlash(uri.path);
return linePath == '/' || uriPath.startsWith(linePath);
}
static String _pathWithTrailingSlash(String path) {
if (path.isEmpty) {
return '/';
}
return path.endsWith('/') ? path : '$path/';
}
static List<String> _normalizedUniqueUrls(Iterable<String> values) {
final urls = <String>[];
final seen = <String>{};
for (final value in values) {
final normalized = _tryNormalizeHomeUrl(value);
if (normalized == null || seen.contains(normalized)) {
continue;
}
urls.add(normalized);
seen.add(normalized);
}
return List.unmodifiable(urls);
}
static String? _tryNormalizeHomeUrl(String value) {
try {
return _normalizeHomeUrl(value);
} catch (_) {
return null;
}
}
static String _normalizeHomeUrl(String host) {
final value = host.trim();
if (value.isEmpty) {
throw const FormatException('Empty H5 line URL');
}
final normalized =
value.startsWith('http://') || value.startsWith('https://')
? value
: 'https://$value';
final uri = Uri.parse(normalized);
final path = uri.path.isEmpty ? '/' : uri.path;
return uri.replace(path: path).toString();
}
}