Refact. Build flutter web (#7472)

* Refact. Build flutter web

Signed-off-by: fufesou <shuanglongchen@yeah.net>

* Refact. Flutter web, wrap Platform.xx

Signed-off-by: fufesou <shuanglongchen@yeah.net>

---------

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou
2024-03-22 13:16:37 +08:00
committed by GitHub
parent 285e298a8b
commit 9558974080
14 changed files with 1625 additions and 54 deletions

View File

@@ -3,11 +3,13 @@ import 'package:flutter_gpu_texture_renderer/flutter_gpu_texture_renderer.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/models/model.dart';
import 'package:get/get.dart';
import 'package:texture_rgba_renderer/texture_rgba_renderer.dart';
import '../../common.dart';
import './platform_model.dart';
import 'package:texture_rgba_renderer/texture_rgba_renderer.dart'
if (dart.library.html) 'package:flutter_hbb/web/texture_rgba_renderer.dart';
// Feature flutter_texture_render need to be enabled if feature gpucodec is enabled.
final useTextureRender =
bind.mainHasPixelbufferTextureRender() || bind.mainHasGpuTextureRender();

View File

@@ -9,7 +9,6 @@ import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/generated_bridge.dart';
import 'package:flutter_hbb/models/ab_model.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_hbb/models/cm_file_model.dart';
@@ -39,6 +38,9 @@ import '../common/widgets/dialog.dart';
import 'input_model.dart';
import 'platform_model.dart';
import 'package:flutter_hbb/generated_bridge.dart'
if (dart.library.html) 'package:flutter_hbb/web/bridge.dart';
typedef HandleMsgBox = Function(Map<String, dynamic> evt, String id);
typedef ReconnectHandle = Function(OverlayDialogManager, SessionID, bool);
final _constSessionId = Uuid().v4obj();

View File

@@ -1,5 +1,6 @@
import 'package:flutter_hbb/generated_bridge.dart';
import 'native_model.dart' if (dart.library.html) 'web_model.dart';
import 'package:flutter_hbb/generated_bridge.dart'
if (dart.library.html) 'package:flutter_hbb/web/bridge.dart';
final platformFFI = PlatformFFI.instance;
final localeName = PlatformFFI.localeName;

View File

@@ -3,15 +3,23 @@
import 'dart:convert';
import 'dart:typed_data';
import 'dart:js';
import '../common.dart';
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<StreamSubscription<MouseEvent>> mouseListeners = [];
final List<StreamSubscription<KeyboardEvent>> keyListeners = [];
typedef HandleEvent = Future<void> Function(Map<String, dynamic> evt);
class PlatformFFI {
final _eventHandlers = <String, Map<String, HandleEvent>>{};
late RustdeskImpl _ffiBind;
static String getByName(String name, [String arg = '']) {
return context.callMethod('getByName', [name, arg]);
}
@@ -24,15 +32,78 @@ class PlatformFFI {
static final PlatformFFI instance = PlatformFFI._();
static get localeName => window.navigator.language;
RustdeskImpl get ffiBind => _ffiBind;
static Future<void> init(String appType) async {
isWeb = true;
static Future<String> 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<bool> tryHandle(Map<String, dynamic> 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<void> init(String appType) async {
isWebDesktop = !context.callMethod('isMobile');
context.callMethod('init');
version = getByName('version');
}
static void setEventCallback(void Function(Map<String, dynamic>) fun) {
void setEventCallback(void Function(Map<String, dynamic>) fun) {
context["onGlobalEvent"] = (String message) {
try {
Map<String, dynamic> event = json.decode(message);
@@ -43,7 +114,7 @@ class PlatformFFI {
};
}
static void setRgbaCallback(void Function(Uint8List) fun) {
void setRgbaCallback(void Function(Uint8List) fun) {
context["onRgba"] = (Uint8List? rgba) {
if (rgba != null) {
fun(rgba);
@@ -51,12 +122,12 @@ class PlatformFFI {
};
}
static void startDesktopWebListener() {
void startDesktopWebListener() {
mouseListeners.add(
window.document.onContextMenu.listen((evt) => evt.preventDefault()));
}
static void stopDesktopWebListener() {
void stopDesktopWebListener() {
for (var ml in mouseListeners) {
ml.cancel();
}
@@ -67,9 +138,14 @@ class PlatformFFI {
keyListeners.clear();
}
static void setMethodCallHandler(FMethod callback) {}
void setMethodCallHandler(FMethod callback) {}
static Future<bool> invokeMethod(String method, [dynamic arguments]) async {
invokeMethod(String method, [dynamic arguments]) async {
return true;
}
// just for compilation
void syncAndroidServiceAppDirConfigPath() {
throw UnimplementedError();
}
}