// ignore_for_file: avoid_web_libraries_in_flutter import 'dart:convert'; import 'dart:typed_data'; import 'dart:js'; import 'dart:html'; import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter_hbb/web/bridge.dart'; import 'package:flutter_hbb/common.dart'; final List> mouseListeners = []; final List> keyListeners = []; typedef HandleEvent = Future Function(Map evt); class PlatformFFI { final _eventHandlers = >{}; final RustdeskImpl _ffiBind = RustdeskImpl(); static String getByName(String name, [String arg = '']) { return context.callMethod('getByName', [name, arg]); } static void setByName(String name, [String value = '']) { context.callMethod('setByName', [name, value]); } PlatformFFI._(); static final PlatformFFI instance = PlatformFFI._(); static get localeName => window.navigator.language; RustdeskImpl get ffiBind => _ffiBind; static Future getVersion() async { throw UnimplementedError(); } bool registerEventHandler( String eventName, String handlerName, HandleEvent handler) { debugPrint('registerEventHandler $eventName $handlerName'); var handlers = _eventHandlers[eventName]; if (handlers == null) { _eventHandlers[eventName] = {handlerName: handler}; return true; } else { if (handlers.containsKey(handlerName)) { return false; } else { handlers[handlerName] = handler; return true; } } } void unregisterEventHandler(String eventName, String handlerName) { debugPrint('unregisterEventHandler $eventName $handlerName'); var handlers = _eventHandlers[eventName]; if (handlers != null) { handlers.remove(handlerName); } } Future tryHandle(Map evt) async { final name = evt['name']; if (name != null) { final handlers = _eventHandlers[name]; if (handlers != null) { if (handlers.isNotEmpty) { for (var handler in handlers.values) { await handler(evt); } return true; } } } return false; } String translate(String name, String locale) => _ffiBind.translate(name: name, locale: locale); Uint8List? getRgba(SessionID sessionId, int display, int bufSize) { throw UnimplementedError(); } int getRgbaSize(SessionID sessionId, int display) => _ffiBind.sessionGetRgbaSize(sessionId: sessionId, display: display); void nextRgba(SessionID sessionId, int display) => _ffiBind.sessionNextRgba(sessionId: sessionId, display: display); void registerPixelbufferTexture(SessionID sessionId, int display, int ptr) => _ffiBind.sessionRegisterPixelbufferTexture( sessionId: sessionId, display: display, ptr: ptr); void registerGpuTexture(SessionID sessionId, int display, int ptr) => _ffiBind.sessionRegisterGpuTexture( sessionId: sessionId, display: display, ptr: ptr); Future init(String appType) async { context.callMethod('init'); version = getByName('version'); window.onContextMenu.listen((event) { event.preventDefault(); }); context['onRegisteredEvent'] = (String message) { try { Map event = json.decode(message); tryHandle(event); } catch (e) { print('json.decode fail(): $e'); } }; } void setEventCallback(void Function(Map) fun) { context["onGlobalEvent"] = (String message) { try { Map event = json.decode(message); fun(event); } catch (e) { print('json.decode fail(): $e'); } }; } void setRgbaCallback(void Function(int, Uint8List) fun) { context["onRgba"] = (int display, Uint8List? rgba) { if (rgba != null) { fun(display, rgba); } }; } void startDesktopWebListener() { mouseListeners.add( window.document.onContextMenu.listen((evt) => evt.preventDefault())); } void stopDesktopWebListener() { for (var ml in mouseListeners) { ml.cancel(); } mouseListeners.clear(); for (var kl in keyListeners) { kl.cancel(); } keyListeners.clear(); } void setMethodCallHandler(FMethod callback) {} invokeMethod(String method, [dynamic arguments]) async { return true; } // just for compilation void syncAndroidServiceAppDirConfigPath() {} }