Merge pull request #1633 from Heap-Hop/refactor_input_model

Refactor input model for mobile and desktop
This commit is contained in:
RustDesk
2022-09-27 23:38:44 +08:00
committed by GitHub
15 changed files with 564 additions and 693 deletions

View File

@@ -6,6 +6,8 @@ import 'package:flutter_hbb/models/platform_model.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../common.dart';
class AbModel with ChangeNotifier {
var abLoading = false;
var abError = "";
@@ -27,7 +29,7 @@ class AbModel with ChangeNotifier {
final api = "${await getApiServer()}/api/ab/get";
try {
final resp =
await http.post(Uri.parse(api), headers: await _getHeaders());
await http.post(Uri.parse(api), headers: await getHttpHeaders());
if (resp.body.isNotEmpty && resp.body.toLowerCase() != "null") {
Map<String, dynamic> json = jsonDecode(resp.body);
if (json.containsKey('error')) {
@@ -61,10 +63,6 @@ class AbModel with ChangeNotifier {
notifyListeners();
}
Future<Map<String, String>>? _getHeaders() {
return _ffi?.getHttpHeaders();
}
void addId(String id) async {
if (idContainBy(id)) {
return;
@@ -93,7 +91,7 @@ class AbModel with ChangeNotifier {
abLoading = true;
notifyListeners();
final api = "${await getApiServer()}/api/ab";
var authHeaders = await _getHeaders() ?? Map<String, String>();
var authHeaders = await getHttpHeaders();
authHeaders['Content-Type'] = "application/json";
final body = jsonEncode({
"data": jsonEncode({"tags": tags, "peers": peers})

View File

@@ -50,10 +50,9 @@ class ChatModel with ChangeNotifier {
bool get isShowChatPage => _isShowChatPage;
WeakReference<FFI> _ffi;
final WeakReference<FFI> parent;
/// Constructor
ChatModel(this._ffi);
ChatModel(this.parent);
ChatUser get currentUser {
final user = messages[currentID]?.chatUser;
@@ -182,7 +181,7 @@ class ChatModel with ChangeNotifier {
_currentID = id;
notifyListeners();
} else {
final client = _ffi.target?.serverModel.clients
final client = parent.target?.serverModel.clients
.firstWhere((client) => client.id == id);
if (client == null) {
return debugPrint(
@@ -208,23 +207,23 @@ class ChatModel with ChangeNotifier {
if (!_isShowChatPage) {
toggleCMChatPage(id);
}
_ffi.target?.serverModel.jumpTo(id);
parent.target?.serverModel.jumpTo(id);
late final chatUser;
if (id == clientModeID) {
chatUser = ChatUser(
firstName: _ffi.target?.ffiModel.pi.username,
firstName: parent.target?.ffiModel.pi.username,
id: await bind.mainGetLastRemoteId(),
);
} else {
final client = _ffi.target?.serverModel.clients
final client = parent.target?.serverModel.clients
.firstWhere((client) => client.id == id);
if (client == null) {
return debugPrint("Failed to receive msg,user doesn't exist");
}
if (isDesktop) {
window_on_top(null);
var index = _ffi.target?.serverModel.clients
var index = parent.target?.serverModel.clients
.indexWhere((client) => client.id == id);
if (index != null && index >= 0) {
gFFI.serverModel.tabController.jumpTo(index);
@@ -246,8 +245,8 @@ class ChatModel with ChangeNotifier {
if (message.text.isNotEmpty) {
_messages[_currentID]?.insert(message);
if (_currentID == clientModeID) {
if (_ffi.target != null) {
bind.sessionSendChat(id: _ffi.target!.id, text: message.text);
if (parent.target != null) {
bind.sessionSendChat(id: parent.target!.id, text: message.text);
}
} else {
bind.cmSendChat(connId: _currentID, msg: message.text);

View File

@@ -1,55 +1,84 @@
import 'dart:convert';
import 'dart:math';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import '../../models/model.dart';
import '../../models/platform_model.dart';
import '../common.dart';
import '../consts.dart';
import 'dart:ui' as ui;
class Keyboard {
late FFI _ffi;
late String _id;
/// Mouse button enum.
enum MouseButtons { left, right, wheel }
extension ToString on MouseButtons {
String get value {
switch (this) {
case MouseButtons.left:
return 'left';
case MouseButtons.right:
return 'right';
case MouseButtons.wheel:
return 'wheel';
}
}
}
class InputModel {
final WeakReference<FFI> parent;
String keyboardMode = "legacy";
Keyboard(FFI ffi, String id) {
_ffi = ffi;
_id = id;
}
// keyboard
var shift = false;
var ctrl = false;
var alt = false;
var command = false;
// mouse
final isPhysicalMouse = false.obs;
int _lastMouseDownButtons = 0;
get id => parent.target?.id ?? "";
InputModel(this.parent);
KeyEventResult handleRawKeyEvent(FocusNode data, RawKeyEvent e) {
bind.sessionGetKeyboardName(id: _id).then((result) {
bind.sessionGetKeyboardName(id: id).then((result) {
keyboardMode = result.toString();
});
final key = e.logicalKey;
if (e is RawKeyDownEvent) {
if (!e.repeat){
if (e.isAltPressed && !_ffi.alt) {
_ffi.alt = true;
} else if (e.isControlPressed && !_ffi.ctrl) {
_ffi.ctrl = true;
} else if (e.isShiftPressed && !_ffi.shift) {
_ffi.shift = true;
} else if (e.isMetaPressed && !_ffi.command) {
_ffi.command = true;
if (!e.repeat) {
if (e.isAltPressed && !alt) {
alt = true;
} else if (e.isControlPressed && !ctrl) {
ctrl = true;
} else if (e.isShiftPressed && !shift) {
shift = true;
} else if (e.isMetaPressed && !command) {
command = true;
}
}
}
if (e is RawKeyUpEvent) {
if (key == LogicalKeyboardKey.altLeft ||
key == LogicalKeyboardKey.altRight) {
_ffi.alt = false;
alt = false;
} else if (key == LogicalKeyboardKey.controlLeft ||
key == LogicalKeyboardKey.controlRight) {
_ffi.ctrl = false;
ctrl = false;
} else if (key == LogicalKeyboardKey.shiftRight ||
key == LogicalKeyboardKey.shiftLeft) {
_ffi.shift = false;
shift = false;
} else if (key == LogicalKeyboardKey.metaLeft ||
key == LogicalKeyboardKey.metaRight ||
key == LogicalKeyboardKey.superKey) {
_ffi.command = false;
command = false;
}
}
@@ -91,12 +120,20 @@ class Keyboard {
} else {
down = false;
}
inputRawKey(e.character ?? "", keyCode, scanCode, down);
}
_ffi.inputRawKey(e.character ?? "", keyCode, scanCode, down);
/// Send raw Key Event
void inputRawKey(String name, int keyCode, int scanCode, bool down) {
bind.sessionHandleFlutterKeyEvent(
id: id,
name: name,
keycode: keyCode,
scancode: scanCode,
downOrUp: down);
}
void legacyKeyboardMode(RawKeyEvent e) {
final key = e.logicalKey;
if (e is RawKeyDownEvent) {
if (e.repeat) {
sendRawKey(e, press: true);
@@ -114,22 +151,23 @@ class Keyboard {
final label = physicalKeyMap[e.physicalKey.usbHidUsage] ??
logicalKeyMap[e.logicalKey.keyId] ??
e.logicalKey.keyLabel;
_ffi.inputKey(label, down: down, press: press ?? false);
inputKey(label, down: down, press: press ?? false);
}
}
class Mouse {
var _isPhysicalMouse = false;
int _lastMouseDownButtons = 0;
late FFI _ffi;
late String _id;
late double tabBarHeight;
Mouse(FFI ffi, String id, double tabBarHeight_) {
_ffi = ffi;
_id = id;
tabBarHeight = tabBarHeight_;
/// Send key stroke event.
/// [down] indicates the key's state(down or up).
/// [press] indicates a click event(down and up).
void inputKey(String name, {bool? down, bool? press}) {
if (!parent.target!.ffiModel.keyboard()) return;
bind.sessionInputKey(
id: id,
name: name,
down: down ?? false,
press: press ?? true,
alt: alt,
ctrl: ctrl,
shift: shift,
command: command);
}
Map<String, dynamic> getEvent(PointerEvent evt, String type) {
@@ -137,10 +175,10 @@ class Mouse {
out['type'] = type;
out['x'] = evt.position.dx;
out['y'] = evt.position.dy;
if (_ffi.alt) out['alt'] = 'true';
if (_ffi.shift) out['shift'] = 'true';
if (_ffi.ctrl) out['ctrl'] = 'true';
if (_ffi.command) out['command'] = 'true';
if (alt) out['alt'] = 'true';
if (shift) out['shift'] = 'true';
if (ctrl) out['ctrl'] = 'true';
if (command) out['command'] = 'true';
out['buttons'] = evt
.buttons; // left button: 1, right button: 2, middle button: 4, 1 | 2 = 3 (left + right)
if (evt.buttons != 0) {
@@ -151,38 +189,92 @@ class Mouse {
return out;
}
/// Send a mouse tap event(down and up).
void tap(MouseButtons button) {
sendMouse('down', button);
sendMouse('up', button);
}
/// Send scroll event with scroll distance [y].
void scroll(int y) {
bind.sessionSendMouse(
id: id,
msg: json
.encode(modify({'id': id, 'type': 'wheel', 'y': y.toString()})));
}
/// Reset key modifiers to false, including [shift], [ctrl], [alt] and [command].
void resetModifiers() {
shift = ctrl = alt = command = false;
}
/// Modify the given modifier map [evt] based on current modifier key status.
Map<String, String> modify(Map<String, String> evt) {
if (ctrl) evt['ctrl'] = 'true';
if (shift) evt['shift'] = 'true';
if (alt) evt['alt'] = 'true';
if (command) evt['command'] = 'true';
return evt;
}
/// Send mouse press event.
void sendMouse(String type, MouseButtons button) {
if (!parent.target!.ffiModel.keyboard()) return;
bind.sessionSendMouse(
id: id,
msg: json.encode(modify({'type': type, 'buttons': button.value})));
}
void enterOrLeave(bool enter) {
// Fix status
if (!enter) {
resetModifiers();
}
bind.sessionEnterOrLeave(id: id, enter: enter);
}
/// Send mouse movement event with distance in [x] and [y].
void moveMouse(double x, double y) {
if (!parent.target!.ffiModel.keyboard()) return;
var x2 = x.toInt();
var y2 = y.toInt();
bind.sessionSendMouse(
id: id, msg: json.encode(modify({'x': '$x2', 'y': '$y2'})));
}
void onPointHoverImage(PointerHoverEvent e) {
if (e.kind != ui.PointerDeviceKind.mouse) return;
if (!_isPhysicalMouse) {
_isPhysicalMouse = true;
if (!isPhysicalMouse.value) {
isPhysicalMouse.value = true;
}
if (_isPhysicalMouse) {
_ffi.handleMouse(getEvent(e, 'mousemove'), tabBarHeight: tabBarHeight);
if (isPhysicalMouse.value) {
handleMouse(getEvent(e, 'mousemove'));
}
}
void onPointDownImage(PointerDownEvent e) {
debugPrint("onPointDownImage");
if (e.kind != ui.PointerDeviceKind.mouse) {
if (_isPhysicalMouse) {
_isPhysicalMouse = false;
if (isPhysicalMouse.value) {
isPhysicalMouse.value = false;
}
}
if (_isPhysicalMouse) {
_ffi.handleMouse(getEvent(e, 'mousedown'), tabBarHeight: tabBarHeight);
if (isPhysicalMouse.value) {
handleMouse(getEvent(e, 'mousedown'));
}
}
void onPointUpImage(PointerUpEvent e) {
if (e.kind != ui.PointerDeviceKind.mouse) return;
if (_isPhysicalMouse) {
_ffi.handleMouse(getEvent(e, 'mouseup'), tabBarHeight: tabBarHeight);
if (isPhysicalMouse.value) {
handleMouse(getEvent(e, 'mouseup'));
}
}
void onPointMoveImage(PointerMoveEvent e) {
if (e.kind != ui.PointerDeviceKind.mouse) return;
if (_isPhysicalMouse) {
_ffi.handleMouse(getEvent(e, 'mousemove'), tabBarHeight: tabBarHeight);
if (isPhysicalMouse.value) {
handleMouse(getEvent(e, 'mousemove'));
}
}
@@ -201,7 +293,93 @@ class Mouse {
dy = 1;
}
bind.sessionSendMouse(
id: _id, msg: '{"type": "wheel", "x": "$dx", "y": "$dy"}');
id: id, msg: '{"type": "wheel", "x": "$dx", "y": "$dy"}');
}
}
void handleMouse(Map<String, dynamic> evt) {
var type = '';
var isMove = false;
switch (evt['type']) {
case 'mousedown':
type = 'down';
break;
case 'mouseup':
type = 'up';
break;
case 'mousemove':
isMove = true;
break;
default:
return;
}
evt['type'] = type;
double x = evt['x'];
double y = max(0.0, evt['y']);
if (isDesktop) {
final RxBool fullscreen = Get.find(tag: 'fullscreen');
final tabBarHeight = fullscreen.isTrue ? 0 : kDesktopRemoteTabBarHeight;
y = y - tabBarHeight;
}
final canvasModel = parent.target!.canvasModel;
final ffiModel = parent.target!.ffiModel;
if (isMove) {
canvasModel.moveDesktopMouse(x, y);
}
final d = ffiModel.display;
if (canvasModel.scrollStyle == ScrollStyle.scrollbar) {
final imageWidth = d.width * canvasModel.scale;
final imageHeight = d.height * canvasModel.scale;
x += imageWidth * canvasModel.scrollX;
y += imageHeight * canvasModel.scrollY;
// boxed size is a center widget
if (canvasModel.size.width > imageWidth) {
x -= ((canvasModel.size.width - imageWidth) / 2);
}
if (canvasModel.size.height > imageHeight) {
y -= ((canvasModel.size.height - imageHeight) / 2);
}
} else {
x -= canvasModel.x;
y -= canvasModel.y;
}
x /= canvasModel.scale;
y /= canvasModel.scale;
x += d.x;
y += d.y;
if (type != '') {
x = 0;
y = 0;
}
// fix mouse out of bounds
x = min(max(0.0, x), d.width.toDouble());
y = min(max(0.0, y), d.height.toDouble());
evt['x'] = '${x.round()}';
evt['y'] = '${y.round()}';
var buttons = '';
switch (evt['buttons']) {
case 1:
buttons = 'left';
break;
case 2:
buttons = 'right';
break;
case 4:
buttons = 'wheel';
break;
}
evt['buttons'] = buttons;
bind.sessionSendMouse(id: id, msg: json.encode(evt));
}
/// Web only
void listenToMouse(bool yesOrNo) {
if (yesOrNo) {
platformFFI.startDesktopWebListener();
} else {
platformFFI.stopDesktopWebListener();
}
}
}

View File

@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'dart:ui' as ui;
@@ -23,6 +22,7 @@ import '../common.dart';
import '../common/shared_state.dart';
import '../utils/image.dart' as img;
import '../mobile/widgets/dialog.dart';
import 'input_model.dart';
import 'platform_model.dart';
typedef HandleMsgBox = Function(Map<String, dynamic> evt, String id);
@@ -725,15 +725,9 @@ class CursorModel with ChangeNotifier {
return h - thresh;
}
touch(double x, double y, MouseButtons button) {
moveLocal(x, y);
parent.target?.moveMouse(_x, _y);
parent.target?.tap(button);
}
move(double x, double y) {
moveLocal(x, y);
parent.target?.moveMouse(_x, _y);
parent.target?.inputModel.moveMouse(_x, _y);
}
moveLocal(double x, double y) {
@@ -748,7 +742,7 @@ class CursorModel with ChangeNotifier {
reset() {
_x = _displayOriginX;
_y = _displayOriginY;
parent.target?.moveMouse(_x, _y);
parent.target?.inputModel.moveMouse(_x, _y);
parent.target?.canvasModel.clear(true);
notifyListeners();
}
@@ -759,7 +753,7 @@ class CursorModel with ChangeNotifier {
final scale = parent.target?.canvasModel.scale ?? 1.0;
_x += dx / scale;
_y += dy / scale;
parent.target?.moveMouse(_x, _y);
parent.target?.inputModel.moveMouse(_x, _y);
notifyListeners();
return;
}
@@ -824,7 +818,7 @@ class CursorModel with ChangeNotifier {
parent.target?.canvasModel.panY(-dy);
}
parent.target?.moveMouse(_x, _y);
parent.target?.inputModel.moveMouse(_x, _y);
notifyListeners();
}
@@ -894,7 +888,7 @@ class CursorModel with ChangeNotifier {
_displayOriginY = y;
_x = x + 1;
_y = y + 1;
parent.target?.moveMouse(x, y);
parent.target?.inputModel.moveMouse(x, y);
parent.target?.canvasModel.resetOffset();
notifyListeners();
}
@@ -905,7 +899,7 @@ class CursorModel with ChangeNotifier {
_displayOriginY = y;
_x = xCursor;
_y = yCursor;
parent.target?.moveMouse(x, y);
parent.target?.inputModel.moveMouse(x, y);
notifyListeners();
}
@@ -1011,31 +1005,11 @@ class RecordingModel with ChangeNotifier {
}
}
/// Mouse button enum.
enum MouseButtons { left, right, wheel }
extension ToString on MouseButtons {
String get value {
switch (this) {
case MouseButtons.left:
return 'left';
case MouseButtons.right:
return 'right';
case MouseButtons.wheel:
return 'wheel';
}
}
}
enum ConnType { defaultConn, fileTransfer, portForward, rdp }
/// Flutter state manager and data communication with the Rust core.
class FFI {
var id = '';
var shift = false;
var ctrl = false;
var alt = false;
var command = false;
var version = '';
var connType = ConnType.defaultConn;
@@ -1053,6 +1027,7 @@ class FFI {
late final UserModel userModel; // global
late final QualityMonitorModel qualityMonitorModel; // session
late final RecordingModel recordingModel; // recording
late final InputModel inputModel; // session
FFI() {
imageModel = ImageModel(WeakReference(this));
@@ -1066,89 +1041,11 @@ class FFI {
userModel = UserModel(WeakReference(this));
qualityMonitorModel = QualityMonitorModel(WeakReference(this));
recordingModel = RecordingModel(WeakReference(this));
inputModel = InputModel(WeakReference(this));
}
/// Send a mouse tap event(down and up).
tap(MouseButtons button) {
sendMouse('down', button);
sendMouse('up', button);
}
/// Send scroll event with scroll distance [y].
scroll(int y) {
bind.sessionSendMouse(
id: id,
msg: json
.encode(modify({'id': id, 'type': 'wheel', 'y': y.toString()})));
}
/// Reset key modifiers to false, including [shift], [ctrl], [alt] and [command].
resetModifiers() {
shift = ctrl = alt = command = false;
}
/// Modify the given modifier map [evt] based on current modifier key status.
Map<String, String> modify(Map<String, String> evt) {
if (ctrl) evt['ctrl'] = 'true';
if (shift) evt['shift'] = 'true';
if (alt) evt['alt'] = 'true';
if (command) evt['command'] = 'true';
return evt;
}
/// Send mouse press event.
sendMouse(String type, MouseButtons button) {
if (!ffiModel.keyboard()) return;
bind.sessionSendMouse(
id: id,
msg: json.encode(modify({'type': type, 'buttons': button.value})));
}
/// Send raw Key Event
inputRawKey(String name, int keyCode, int scanCode, bool down) {
bind.sessionHandleFlutterKeyEvent(
id: id,
name: name,
keycode: keyCode,
scancode: scanCode,
downOrUp: down);
}
enterOrLeave(bool enter) {
// Fix status
if (!enter) {
resetModifiers();
}
bind.sessionEnterOrLeave(id: id, enter: enter);
}
/// Send key stroke event.
/// [down] indicates the key's state(down or up).
/// [press] indicates a click event(down and up).
inputKey(String name, {bool? down, bool? press}) {
if (!ffiModel.keyboard()) return;
bind.sessionInputKey(
id: id,
name: name,
down: down ?? false,
press: press ?? true,
alt: alt,
ctrl: ctrl,
shift: shift,
command: command);
}
/// Send mouse movement event with distance in [x] and [y].
moveMouse(double x, double y) {
if (!ffiModel.keyboard()) return;
var x2 = x.toInt();
var y2 = y.toInt();
bind.sessionSendMouse(
id: id, msg: json.encode(modify({'x': '$x2', 'y': '$y2'})));
}
/// Connect with the given [id]. Only transfer file if [isFileTransfer], only port forward if [isPortForward].
connect(String id,
/// Start with the given [id]. Only transfer file if [isFileTransfer], only port forward if [isPortForward].
void start(String id,
{bool isFileTransfer = false,
bool isPortForward = false,
double tabBarHeight = 0.0}) {
@@ -1192,7 +1089,7 @@ class FFI {
}
/// Login with [password], choose if the client should [remember] it.
login(String id, String password, bool remember) {
void login(String id, String password, bool remember) {
bind.sessionLogin(id: id, password: password, remember: remember);
}
@@ -1209,118 +1106,17 @@ class FFI {
cursorModel.clear();
ffiModel.clear();
canvasModel.clear();
resetModifiers();
inputModel.resetModifiers();
debugPrint('model $id closed');
}
handleMouse(Map<String, dynamic> evt, {double tabBarHeight = 0.0}) {
var type = '';
var isMove = false;
switch (evt['type']) {
case 'mousedown':
type = 'down';
break;
case 'mouseup':
type = 'up';
break;
case 'mousemove':
isMove = true;
break;
default:
return;
}
evt['type'] = type;
double x = evt['x'];
double y = max(0.0, (evt['y'] as double) - tabBarHeight);
if (isMove) {
canvasModel.moveDesktopMouse(x, y);
}
final d = ffiModel.display;
if (canvasModel.scrollStyle == ScrollStyle.scrollbar) {
final imageWidth = d.width * canvasModel.scale;
final imageHeight = d.height * canvasModel.scale;
x += imageWidth * canvasModel.scrollX;
y += imageHeight * canvasModel.scrollY;
// boxed size is a center widget
if (canvasModel.size.width > imageWidth) {
x -= ((canvasModel.size.width - imageWidth) / 2);
}
if (canvasModel.size.height > imageHeight) {
y -= ((canvasModel.size.height - imageHeight) / 2);
}
} else {
x -= canvasModel.x;
y -= canvasModel.y;
}
x /= canvasModel.scale;
y /= canvasModel.scale;
x += d.x;
y += d.y;
if (type != '') {
x = 0;
y = 0;
}
// fix mouse out of bounds
x = min(max(0.0, x), d.width.toDouble());
y = min(max(0.0, y), d.height.toDouble());
evt['x'] = '${x.round()}';
evt['y'] = '${y.round()}';
var buttons = '';
switch (evt['buttons']) {
case 1:
buttons = 'left';
break;
case 2:
buttons = 'right';
break;
case 4:
buttons = 'wheel';
break;
}
evt['buttons'] = buttons;
bind.sessionSendMouse(id: id, msg: json.encode(evt));
}
listenToMouse(bool yesOrNo) {
if (yesOrNo) {
platformFFI.startDesktopWebListener();
} else {
platformFFI.stopDesktopWebListener();
}
}
setMethodCallHandler(FMethod callback) {
void setMethodCallHandler(FMethod callback) {
platformFFI.setMethodCallHandler(callback);
}
Future<bool> invokeMethod(String method, [dynamic arguments]) async {
return await platformFFI.invokeMethod(method, arguments);
}
Future<List<String>> getAudioInputs() async {
return await bind.mainGetSoundInputs();
}
Future<String> getDefaultAudioInput() async {
final input = await bind.mainGetOption(key: 'audio-input');
if (input.isEmpty && Platform.isWindows) {
return 'System Sound';
}
return input;
}
setDefaultAudioInput(String input) {
bind.mainSetOption(key: 'audio-input', value: input);
}
Future<Map<String, String>> getHttpHeaders() async {
return {
'Authorization':
'Bearer ${await bind.mainGetLocalOption(key: 'access_token')}'
};
}
}
class Display {
@@ -1349,8 +1145,8 @@ class PeerInfo {
List<Display> displays = [];
}
savePreference(String id, double xCursor, double yCursor, double xCanvas,
double yCanvas, double scale, int currentDisplay) async {
Future<void> savePreference(String id, double xCursor, double yCursor,
double xCanvas, double yCanvas, double scale, int currentDisplay) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final p = <String, dynamic>{};
p['xCursor'] = xCursor;
@@ -1371,12 +1167,12 @@ Future<Map<String, dynamic>?> getPreference(String id) async {
return m;
}
removePreference(String id) async {
void removePreference(String id) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.remove('peer$id');
}
initializeCursorAndCanvas(FFI ffi) async {
Future<void> initializeCursorAndCanvas(FFI ffi) async {
var p = await getPreference(ffi.id);
int currentDisplay = 0;
if (p != null) {
@@ -1396,16 +1192,3 @@ initializeCursorAndCanvas(FFI ffi) async {
ffi.ffiModel.display.x, ffi.ffiModel.display.y, xCursor, yCursor);
ffi.canvasModel.update(xCanvas, yCanvas, scale);
}
/// Translate text based on the pre-defined dictionary.
/// note: params [FFI?] can be used to replace global FFI implementation
/// for example: during global initialization, gFFI not exists yet.
// String translate(String name, {FFI? ffi}) {
// if (name.startsWith('Failed to') && name.contains(': ')) {
// return name.split(': ').map((x) => translate(x)).join(': ');
// }
// var a = 'translate';
// var b = '{"locale": "$localeName", "text": "$name"}';
//
// return (ffi ?? gFFI).getByName(a, b);
// }

View File

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../common.dart';
import 'model.dart';
import 'platform_model.dart';
@@ -35,7 +36,7 @@ class UserModel extends ChangeNotifier {
"id": await bind.mainGetMyId(),
"uuid": await bind.mainGetUuid(),
},
headers: await _getHeaders());
headers: await getHttpHeaders());
await Future.wait([
bind.mainSetLocalOption(key: 'access_token', value: ''),
bind.mainSetLocalOption(key: 'user_info', value: ''),
@@ -46,10 +47,6 @@ class UserModel extends ChangeNotifier {
notifyListeners();
}
Future<Map<String, String>>? _getHeaders() {
return parent.target?.getHttpHeaders();
}
Future<Map<String, dynamic>> login(String userName, String pass) async {
final url = await bind.mainGetApiServer();
try {