Compare commits
2 Commits
3184d42cbb
...
c0d5021f8c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0d5021f8c | ||
|
|
fb207d667e |
@@ -28,6 +28,23 @@ Future launchURL(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _externalUrlForScheme(String url, String scheme) {
|
||||||
|
final prefix = '$scheme:';
|
||||||
|
if (!url.toLowerCase().startsWith(prefix)) return url;
|
||||||
|
|
||||||
|
final stripped = url
|
||||||
|
.substring(prefix.length)
|
||||||
|
.replaceFirst(RegExp(r'^/+'), '');
|
||||||
|
final uri = Uri.tryParse(stripped);
|
||||||
|
if (uri != null &&
|
||||||
|
(uri.scheme == 'http' || uri.scheme == 'https') &&
|
||||||
|
uri.host.isNotEmpty) {
|
||||||
|
return stripped;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
class BootstrapProgress {
|
class BootstrapProgress {
|
||||||
final String phase;
|
final String phase;
|
||||||
final double percent;
|
final double percent;
|
||||||
@@ -492,6 +509,7 @@ class _LoadingScreenState extends State<LoadingScreen>
|
|||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
child: SafeArea(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
@@ -532,7 +550,7 @@ class _LoadingScreenState extends State<LoadingScreen>
|
|||||||
_showWebViewProgress(progress: 0);
|
_showWebViewProgress(progress: 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
debugPrint('onLoadStart: $url');
|
debugPrint('WebView onLoadStart: $url');
|
||||||
},
|
},
|
||||||
onProgressChanged: (controller, progress) {
|
onProgressChanged: (controller, progress) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
@@ -550,7 +568,7 @@ class _LoadingScreenState extends State<LoadingScreen>
|
|||||||
if (progress >= 100) {
|
if (progress >= 100) {
|
||||||
_hideWebViewProgressSoon();
|
_hideWebViewProgressSoon();
|
||||||
}
|
}
|
||||||
debugPrint('onProgressChanged: $progress');
|
debugPrint('WebView onProgressChanged: $progress');
|
||||||
},
|
},
|
||||||
onLoadStop: (controller, url) async {
|
onLoadStop: (controller, url) async {
|
||||||
final loadedUrl = url?.toString();
|
final loadedUrl = url?.toString();
|
||||||
@@ -572,7 +590,7 @@ class _LoadingScreenState extends State<LoadingScreen>
|
|||||||
_hideWebViewProgressSoon();
|
_hideWebViewProgressSoon();
|
||||||
}
|
}
|
||||||
_reportWebViewEvent('load_success', {
|
_reportWebViewEvent('load_success', {
|
||||||
'rs': _safeReportUrl(loadedUrl),
|
'url': _safeReportUrl(loadedUrl),
|
||||||
});
|
});
|
||||||
debugPrint('WebView onLoadStop: $url');
|
debugPrint('WebView onLoadStop: $url');
|
||||||
},
|
},
|
||||||
@@ -617,9 +635,30 @@ class _LoadingScreenState extends State<LoadingScreen>
|
|||||||
(controller, navigationAction) async {
|
(controller, navigationAction) async {
|
||||||
final requestUrl = navigationAction.request.url
|
final requestUrl = navigationAction.request.url
|
||||||
?.toString();
|
?.toString();
|
||||||
if (requestUrl != null && requestUrl.isNotEmpty) {
|
if (requestUrl != null &&
|
||||||
|
requestUrl.isNotEmpty) {
|
||||||
_currentWebViewUrl = requestUrl;
|
_currentWebViewUrl = requestUrl;
|
||||||
}
|
}
|
||||||
|
final requestScheme = navigationAction
|
||||||
|
.request
|
||||||
|
.url
|
||||||
|
?.scheme
|
||||||
|
.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
if (requestUrl != null &&
|
||||||
|
requestUrl.isNotEmpty &&
|
||||||
|
requestScheme != null &&
|
||||||
|
NextStep.I.openWindows.contains(
|
||||||
|
requestScheme,
|
||||||
|
)) {
|
||||||
|
await launchURL(
|
||||||
|
_externalUrlForScheme(
|
||||||
|
requestUrl,
|
||||||
|
requestScheme,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return NavigationActionPolicy.CANCEL;
|
||||||
|
}
|
||||||
final isRedirect =
|
final isRedirect =
|
||||||
navigationAction.isRedirect == true;
|
navigationAction.isRedirect == true;
|
||||||
if (isRedirect && mounted) {
|
if (isRedirect && mounted) {
|
||||||
@@ -658,6 +697,7 @@ class _LoadingScreenState extends State<LoadingScreen>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ class NextStep {
|
|||||||
bool _j = false;
|
bool _j = false;
|
||||||
bool get j => _j;
|
bool get j => _j;
|
||||||
|
|
||||||
|
Set<String> openWindows = {};
|
||||||
|
|
||||||
NextStep._();
|
NextStep._();
|
||||||
static final NextStep I = NextStep._();
|
static final NextStep I = NextStep._();
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@ class NextStep {
|
|||||||
if (rs is! Map<String, dynamic>) return;
|
if (rs is! Map<String, dynamic>) return;
|
||||||
|
|
||||||
_applyEventMap(rs['f']);
|
_applyEventMap(rs['f']);
|
||||||
|
openWindows = _parseOpenWindowSchemes(rs['o']);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint("loadAppInfo error $e");
|
debugPrint("loadAppInfo error $e");
|
||||||
}
|
}
|
||||||
@@ -261,6 +264,19 @@ void _applyEventMap(dynamic value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<String> _parseOpenWindowSchemes(dynamic value) {
|
||||||
|
if (value is! List) return {};
|
||||||
|
|
||||||
|
return value
|
||||||
|
.map((item) => item?.toString().trim().toLowerCase() ?? '')
|
||||||
|
.map(
|
||||||
|
(item) =>
|
||||||
|
item.endsWith(':') ? item.substring(0, item.length - 1) : item,
|
||||||
|
)
|
||||||
|
.where((item) => item.isNotEmpty)
|
||||||
|
.toSet();
|
||||||
|
}
|
||||||
|
|
||||||
bool _isValidToken(String? token) {
|
bool _isValidToken(String? token) {
|
||||||
return token != null && token.trim().length > 5;
|
return token != null && token.trim().length > 5;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user