216 lines
5.6 KiB
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();
|
|
}
|
|
}
|