web_model.dart 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // ignore_for_file: avoid_web_libraries_in_flutter
  2. import 'dart:convert';
  3. import 'dart:js_interop';
  4. import 'dart:typed_data';
  5. import 'dart:js';
  6. import 'dart:html';
  7. import 'dart:async';
  8. import 'package:flutter/foundation.dart';
  9. import 'package:flutter_hbb/models/state_model.dart';
  10. import 'package:flutter_hbb/web/bridge.dart';
  11. import 'package:flutter_hbb/common.dart';
  12. final List<StreamSubscription<MouseEvent>> mouseListeners = [];
  13. final List<StreamSubscription<KeyboardEvent>> keyListeners = [];
  14. typedef HandleEvent = Future<void> Function(Map<String, dynamic> evt);
  15. class PlatformFFI {
  16. final _eventHandlers = <String, Map<String, HandleEvent>>{};
  17. final RustdeskImpl _ffiBind = RustdeskImpl();
  18. static String getByName(String name, [String arg = '']) {
  19. return context.callMethod('getByName', [name, arg]);
  20. }
  21. static void setByName(String name, [String value = '']) {
  22. context.callMethod('setByName', [name, value]);
  23. }
  24. PlatformFFI._() {
  25. window.document.addEventListener(
  26. 'visibilitychange',
  27. (event) => {
  28. stateGlobal.isWebVisible =
  29. window.document.visibilityState == 'visible'
  30. });
  31. }
  32. static final PlatformFFI instance = PlatformFFI._();
  33. static get localeName => window.navigator.language;
  34. RustdeskImpl get ffiBind => _ffiBind;
  35. static Future<String> getVersion() async {
  36. throw UnimplementedError();
  37. }
  38. bool registerEventHandler(
  39. String eventName, String handlerName, HandleEvent handler) {
  40. debugPrint('registerEventHandler $eventName $handlerName');
  41. var handlers = _eventHandlers[eventName];
  42. if (handlers == null) {
  43. _eventHandlers[eventName] = {handlerName: handler};
  44. return true;
  45. } else {
  46. if (handlers.containsKey(handlerName)) {
  47. return false;
  48. } else {
  49. handlers[handlerName] = handler;
  50. return true;
  51. }
  52. }
  53. }
  54. void unregisterEventHandler(String eventName, String handlerName) {
  55. debugPrint('unregisterEventHandler $eventName $handlerName');
  56. var handlers = _eventHandlers[eventName];
  57. if (handlers != null) {
  58. handlers.remove(handlerName);
  59. }
  60. }
  61. Future<bool> tryHandle(Map<String, dynamic> evt) async {
  62. final name = evt['name'];
  63. if (name != null) {
  64. final handlers = _eventHandlers[name];
  65. if (handlers != null) {
  66. if (handlers.isNotEmpty) {
  67. for (var handler in handlers.values) {
  68. await handler(evt);
  69. }
  70. return true;
  71. }
  72. }
  73. }
  74. return false;
  75. }
  76. String translate(String name, String locale) =>
  77. _ffiBind.translate(name: name, locale: locale);
  78. Uint8List? getRgba(SessionID sessionId, int display, int bufSize) {
  79. throw UnimplementedError();
  80. }
  81. int getRgbaSize(SessionID sessionId, int display) =>
  82. _ffiBind.sessionGetRgbaSize(sessionId: sessionId, display: display);
  83. void nextRgba(SessionID sessionId, int display) =>
  84. _ffiBind.sessionNextRgba(sessionId: sessionId, display: display);
  85. void registerPixelbufferTexture(SessionID sessionId, int display, int ptr) =>
  86. _ffiBind.sessionRegisterPixelbufferTexture(
  87. sessionId: sessionId, display: display, ptr: ptr);
  88. void registerGpuTexture(SessionID sessionId, int display, int ptr) =>
  89. _ffiBind.sessionRegisterGpuTexture(
  90. sessionId: sessionId, display: display, ptr: ptr);
  91. Future<void> init(String appType) async {
  92. Completer completer = Completer();
  93. context["onInitFinished"] = () {
  94. completer.complete();
  95. };
  96. context.callMethod('init');
  97. version = getByName('version');
  98. window.onContextMenu.listen((event) {
  99. event.preventDefault();
  100. });
  101. context['onRegisteredEvent'] = (String message) {
  102. try {
  103. Map<String, dynamic> event = json.decode(message);
  104. tryHandle(event);
  105. } catch (e) {
  106. print('json.decode fail(): $e');
  107. }
  108. };
  109. return completer.future;
  110. }
  111. void setEventCallback(void Function(Map<String, dynamic>) fun) {
  112. context["onGlobalEvent"] = (String message) {
  113. try {
  114. Map<String, dynamic> event = json.decode(message);
  115. fun(event);
  116. } catch (e) {
  117. print('json.decode fail(): $e');
  118. }
  119. };
  120. }
  121. void setRgbaCallback(void Function(int, Uint8List) fun) {
  122. context["onRgba"] = (int display, Uint8List? rgba) {
  123. if (rgba != null) {
  124. fun(display, rgba);
  125. }
  126. };
  127. }
  128. void startDesktopWebListener() {
  129. mouseListeners.add(
  130. window.document.onContextMenu.listen((evt) => evt.preventDefault()));
  131. }
  132. void stopDesktopWebListener() {
  133. for (var ml in mouseListeners) {
  134. ml.cancel();
  135. }
  136. mouseListeners.clear();
  137. for (var kl in keyListeners) {
  138. kl.cancel();
  139. }
  140. keyListeners.clear();
  141. }
  142. void setMethodCallHandler(FMethod callback) {}
  143. invokeMethod(String method, [dynamic arguments]) async {
  144. return true;
  145. }
  146. // just for compilation
  147. void syncAndroidServiceAppDirConfigPath() {}
  148. void setFullscreenCallback(void Function(bool) fun) {
  149. context["onFullscreenChanged"] = (bool v) {
  150. fun(v);
  151. };
  152. }
  153. }