From 8d4012596d7f75fccee014466cb044c235d84a8f Mon Sep 17 00:00:00 2001 From: Booker Date: Mon, 25 May 2026 15:28:37 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E6=9D=83=E9=99=90=E8=AF=B7=E6=B1=82=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81=E9=9F=B3=E9=A2=91=E5=92=8C?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E6=9D=83=E9=99=90=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/main.dart | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index dec5a7e..b9f8da0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -239,11 +239,13 @@ class _H5ShellPageState extends State with WidgetsBindingObserver { } void _handleShellBridgeMessage(JavaScriptMessage message) { + Map? payload; String? type; try { final decoded = jsonDecode(message.message); - if (decoded is Map) { - type = decoded['type'] as String?; + if (decoded is Map) { + payload = Map.from(decoded); + type = payload['type'] as String?; } } catch (_) { type = message.message; @@ -252,6 +254,50 @@ class _H5ShellPageState extends State with WidgetsBindingObserver { if (type == 'openAppSettings') { unawaited(openAppSettings()); } + if (type == 'requestMediaPermissions' && payload != null) { + unawaited(_handleMediaPermissionBridgeRequest(payload)); + } + } + + Future _handleMediaPermissionBridgeRequest( + Map payload, + ) async { + final requestId = payload['requestId'] as String?; + if (requestId == null || requestId.isEmpty) { + return; + } + + final permissions = {}; + if (payload['audio'] == true) { + permissions.add(Permission.microphone); + } + if (payload['video'] == true) { + permissions.add(Permission.camera); + } + + final statuses = permissions.isEmpty + ? [] + : await Future.wait( + permissions.map((permission) => permission.request())); + final granted = statuses.every( + (status) => status.isGranted || status.isLimited, + ); + final permanentlyDenied = + statuses.any((status) => status.isPermanentlyDenied); + final restricted = statuses.any((status) => status.isRestricted); + + final detail = jsonEncode({ + 'requestId': requestId, + 'granted': granted, + 'permanentlyDenied': permanentlyDenied, + 'restricted': restricted, + }); + final script = ''' +(() => { + window.dispatchEvent(new CustomEvent('openim-shell-media-permission-result', { detail: $detail })); +})(); +'''; + await _runJavaScriptSafely(script); } void _showTransientShellCover() {