refactor set/getByName "peers" "option"

This commit is contained in:
csf
2022-08-08 17:53:51 +08:00
parent 0ef1659b87
commit c5d0628291
15 changed files with 414 additions and 553 deletions

View File

@@ -391,3 +391,10 @@ Future<void> initGlobalFFI() async {
// global shared preference
await Get.putAsync(() => SharedPreferences.getInstance());
}
String translate(String name) {
if (name.startsWith('Failed to') && name.contains(': ')) {
return name.split(': ').map((x) => translate(x)).join(': ');
}
return platformFFI.translate(name, localeName);
}

View File

@@ -44,13 +44,22 @@ class _ConnectionPageState extends State<ConnectionPage> {
/// Update url. If it's not null, means an update is available.
var _updateUrl = '';
var _menuPos;
Timer? _updateTimer;
@override
void initState() {
super.initState();
if (_idController.text.isEmpty) {
() async {
final lastRemoteId = await bind.mainGetLastRemoteId();
if (lastRemoteId != _idController.text) {
setState(() {
_idController.text = lastRemoteId;
});
}
}();
}
_updateTimer = Timer.periodic(Duration(seconds: 1), (timer) {
updateStatus();
});
@@ -58,7 +67,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
@override
Widget build(BuildContext context) {
if (_idController.text.isEmpty) _idController.text = gFFI.getId();
return Container(
decoration: BoxDecoration(color: isDarkTheme() ? null : MyTheme.grayBg),
child: Column(
@@ -428,7 +436,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
}
updateStatus() async {
svcStopped.value = gFFI.getOption("stop-service") == "Y";
svcStopped.value = bind.mainGetOption(key: "stop-service") == "Y";
final status =
jsonDecode(await bind.mainGetConnectStatus()) as Map<String, dynamic>;
svcStatusCode.value = status["status_num"];
@@ -444,7 +452,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
}
Future<Widget> buildAddressBook(BuildContext context) async {
final token = await gFFI.getLocalOption('access_token');
final token = await bind.mainGetLocalOption(key: 'access_token');
if (token.trim().isEmpty) {
return Center(
child: InkWell(

View File

@@ -7,7 +7,6 @@ import 'package:flutter/services.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/desktop/pages/connection_page.dart';
import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart';
import 'package:flutter_hbb/models/model.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/server_model.dart';
import 'package:get/get.dart';
@@ -156,6 +155,8 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
},
onTap: () async {
final userName = await gFFI.userModel.getUserName();
final enabledInput = await bind.mainGetOption(key: 'enable-audio');
final defaultInput = await gFFI.getDefaultAudioInput();
var menu = <PopupMenuEntry>[
genEnablePopupMenuItem(
translate("Enable Keyboard/Mouse"),
@@ -173,7 +174,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
translate("Enable TCP Tunneling"),
'enable-tunnel',
),
genAudioInputPopupMenuItem(),
genAudioInputPopupMenuItem(enabledInput != "N", defaultInput),
PopupMenuDivider(),
PopupMenuItem(
child: Text(translate("ID/Relay Server")),
@@ -465,49 +466,60 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
Get.find<SharedPreferences>().setString("darkTheme", choice);
}
void onSelectMenu(String value) {
if (value.startsWith('enable-')) {
final option = gFFI.getOption(value);
gFFI.setOption(value, option == "N" ? "" : "N");
} else if (value.startsWith('allow-')) {
final option = gFFI.getOption(value);
void onSelectMenu(String key) async {
if (key.startsWith('enable-')) {
final option = await bind.mainGetOption(key: key);
bind.mainSetOption(key: key, value: option == "N" ? "" : "N");
} else if (key.startsWith('allow-')) {
final option = await bind.mainGetOption(key: key);
final choice = option == "Y" ? "" : "Y";
gFFI.setOption(value, choice);
bind.mainSetOption(key: key, value: choice);
changeTheme(choice);
} else if (value == "stop-service") {
final option = gFFI.getOption(value);
gFFI.setOption(value, option == "Y" ? "" : "Y");
} else if (value == "change-id") {
} else if (key == "stop-service") {
final option = await bind.mainGetOption(key: key);
bind.mainSetOption(key: key, value: option == "Y" ? "" : "Y");
} else if (key == "change-id") {
changeId();
} else if (value == "custom-server") {
} else if (key == "custom-server") {
changeServer();
} else if (value == "whitelist") {
} else if (key == "whitelist") {
changeWhiteList();
} else if (value == "socks5-proxy") {
} else if (key == "socks5-proxy") {
changeSocks5Proxy();
} else if (value == "about") {
} else if (key == "about") {
about();
} else if (value == "logout") {
} else if (key == "logout") {
logOut();
} else if (value == "login") {
} else if (key == "login") {
login();
}
}
PopupMenuItem<String> genEnablePopupMenuItem(String label, String value) {
final v = gFFI.getOption(value);
final isEnable = value.startsWith('enable-') ? v != "N" : v == "Y";
PopupMenuItem<String> genEnablePopupMenuItem(String label, String key) {
Future<bool> getOptionEnable(String key) async {
final v = await bind.mainGetOption(key: key);
return key.startsWith('enable-') ? v != "N" : v == "Y";
}
return PopupMenuItem(
child: Row(
children: [
Offstage(offstage: !isEnable, child: Icon(Icons.check)),
Text(
label,
style: genTextStyle(isEnable),
),
],
),
value: value,
child: FutureBuilder<bool>(
future: getOptionEnable(key),
builder: (context, snapshot) {
var enable = false;
if (snapshot.hasData && snapshot.data!) {
enable = true;
}
return Row(
children: [
Offstage(offstage: !enable, child: Icon(Icons.check)),
Text(
label,
style: genTextStyle(enable),
),
],
);
}),
value: key,
);
}
@@ -518,10 +530,11 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
color: Colors.redAccent, decoration: TextDecoration.lineThrough);
}
PopupMenuItem<String> genAudioInputPopupMenuItem() {
final _enabledInput = gFFI.getOption('enable-audio');
var defaultInput = gFFI.getDefaultAudioInput().obs;
var enabled = (_enabledInput != "N").obs;
PopupMenuItem<String> genAudioInputPopupMenuItem(
bool enableInput, String defaultAudioInput) {
final defaultInput = defaultAudioInput.obs;
final enabled = enableInput.obs;
return PopupMenuItem(
child: FutureBuilder<List<String>>(
future: gFFI.getAudioInputs(),
@@ -569,12 +582,13 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
alignment: Alignment.centerLeft,
child: Text(translate("Audio Input"))),
itemBuilder: (context) => inputList,
onSelected: (dev) {
onSelected: (dev) async {
if (dev == "Mute") {
gFFI.setOption(
'enable-audio', _enabledInput == 'N' ? '' : 'N');
enabled.value = gFFI.getOption('enable-audio') != 'N';
} else if (dev != gFFI.getDefaultAudioInput()) {
await bind.mainSetOption(
key: 'enable-audio', value: enabled.value ? '' : 'N');
enabled.value =
await bind.mainGetOption(key: 'enable-audio') != 'N';
} else if (dev != await gFFI.getDefaultAudioInput()) {
gFFI.setDefaultAudioInput(dev);
defaultInput.value = dev;
}

View File

@@ -89,7 +89,8 @@ class _PeerCardState extends State<_PeerCard>
children: [
Expanded(
child: FutureBuilder<String>(
future: gFFI.getPeerOption(peer.id, 'alias'),
future: bind.mainGetPeerOption(
id: peer.id, key: 'alias'),
builder: (_, snapshot) {
if (snapshot.hasData) {
final name = snapshot.data!.isEmpty
@@ -304,7 +305,7 @@ class _PeerCardState extends State<_PeerCard>
void _rename(String id) async {
var isInProgress = false;
var name = await gFFI.getPeerOption(id, 'alias');
var name = await bind.mainGetPeerOption(id: id, key: 'alias');
if (widget.type == PeerType.ab) {
final peer = gFFI.abModel.peers.firstWhere((p) => id == p['id']);
if (peer == null) {
@@ -359,7 +360,8 @@ class _PeerCardState extends State<_PeerCard>
if (k.currentState != null) {
if (k.currentState!.validate()) {
k.currentState!.save();
await gFFI.setPeerOption(id, 'alias', name);
await bind.mainSetPeerOption(
id: id, key: 'alias', value: name);
if (widget.type == PeerType.ab) {
gFFI.abModel.setPeerOption(id, 'alias', name);
await gFFI.abModel.updateAb();

View File

@@ -7,6 +7,8 @@ import 'package:url_launcher/url_launcher.dart';
import '../../common.dart';
import '../../models/model.dart';
import '../../models/peer_model.dart';
import '../../models/platform_model.dart';
import 'home_page.dart';
import 'remote_page.dart';
import 'scan_page.dart';
@@ -41,6 +43,16 @@ class _ConnectionPageState extends State<ConnectionPage> {
@override
void initState() {
super.initState();
if (_idController.text.isEmpty) {
() async {
final lastRemoteId = await bind.mainGetLastRemoteId();
if (lastRemoteId != _idController.text) {
setState(() {
_idController.text = lastRemoteId;
});
}
}();
}
if (isAndroid) {
Timer(Duration(seconds: 5), () {
_updateUrl = gFFI.getByName('software_update_url');
@@ -52,7 +64,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
@override
Widget build(BuildContext context) {
Provider.of<FfiModel>(context);
if (_idController.text.isEmpty) _idController.text = gFFI.getId();
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
@@ -221,44 +232,52 @@ class _ConnectionPageState extends State<ConnectionPage> {
final n = (windowWidth / (minWidth + 2 * space)).floor();
width = windowWidth / n - 2 * space;
}
final cards = <Widget>[];
var peers = gFFI.peers();
peers.forEach((p) {
cards.add(Container(
width: width,
child: Card(
child: GestureDetector(
onTap: !isWebDesktop ? () => connect('${p.id}') : null,
onDoubleTap: isWebDesktop ? () => connect('${p.id}') : null,
onLongPressStart: (details) {
final x = details.globalPosition.dx;
final y = details.globalPosition.dy;
_menuPos = RelativeRect.fromLTRB(x, y, x, y);
showPeerMenu(context, p.id);
},
child: ListTile(
contentPadding: const EdgeInsets.only(left: 12),
subtitle: Text('${p.username}@${p.hostname}'),
title: Text('${p.id}'),
leading: Container(
padding: const EdgeInsets.all(6),
child: getPlatformImage('${p.platform}'),
color: str2color('${p.id}${p.platform}', 0x7f)),
trailing: InkWell(
child: Padding(
padding: const EdgeInsets.all(12),
child: Icon(Icons.more_vert)),
onTapDown: (e) {
final x = e.globalPosition.dx;
final y = e.globalPosition.dy;
_menuPos = RelativeRect.fromLTRB(x, y, x, y);
},
onTap: () {
showPeerMenu(context, p.id);
}),
)))));
});
return Wrap(children: cards, spacing: space, runSpacing: space);
return FutureBuilder<List<Peer>>(
future: gFFI.peers(),
builder: (context, snapshot) {
final cards = <Widget>[];
if (snapshot.hasData) {
final peers = snapshot.data!;
peers.forEach((p) {
cards.add(Container(
width: width,
child: Card(
child: GestureDetector(
onTap:
!isWebDesktop ? () => connect('${p.id}') : null,
onDoubleTap:
isWebDesktop ? () => connect('${p.id}') : null,
onLongPressStart: (details) {
final x = details.globalPosition.dx;
final y = details.globalPosition.dy;
_menuPos = RelativeRect.fromLTRB(x, y, x, y);
showPeerMenu(context, p.id);
},
child: ListTile(
contentPadding: const EdgeInsets.only(left: 12),
subtitle: Text('${p.username}@${p.hostname}'),
title: Text('${p.id}'),
leading: Container(
padding: const EdgeInsets.all(6),
child: getPlatformImage('${p.platform}'),
color: str2color('${p.id}${p.platform}', 0x7f)),
trailing: InkWell(
child: Padding(
padding: const EdgeInsets.all(12),
child: Icon(Icons.more_vert)),
onTapDown: (e) {
final x = e.globalPosition.dx;
final y = e.globalPosition.dy;
_menuPos = RelativeRect.fromLTRB(x, y, x, y);
},
onTap: () {
showPeerMenu(context, p.id);
}),
)))));
});
}
return Wrap(children: cards, spacing: space, runSpacing: space);
});
}
/// Show the peer menu and handle user's choice.

View File

@@ -9,7 +9,7 @@ import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:zxing2/qrcode.dart';
import '../../common.dart';
import '../../models/model.dart';
import '../../models/platform_model.dart';
class ScanPage extends StatefulWidget {
@override
@@ -153,54 +153,80 @@ class _ScanPageState extends State<ScanPage> {
}
void showServerSettingsWithValue(
String id, String relay, String key, String api) {
final formKey = GlobalKey<FormState>();
final id0 = gFFI.getByName('option', 'custom-rendezvous-server');
final relay0 = gFFI.getByName('option', 'relay-server');
final api0 = gFFI.getByName('option', 'api-server');
final key0 = gFFI.getByName('option', 'key');
String id, String relay, String key, String api) async {
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
String id0 = oldOptions['custom-rendezvous-server'] ?? "";
String relay0 = oldOptions['relay-server'] ?? "";
String api0 = oldOptions['api-server'] ?? "";
String key0 = oldOptions['key'] ?? "";
var isInProgress = false;
final idController = TextEditingController(text: id);
final relayController = TextEditingController(text: relay);
final apiController = TextEditingController(text: api);
String? idServerMsg;
String? relayServerMsg;
String? apiServerMsg;
DialogManager.show((setState, close) {
Future<bool> validate() async {
if (idController.text != id) {
final res = await validateAsync(idController.text);
setState(() => idServerMsg = res);
if (idServerMsg != null) return false;
id = idController.text;
}
if (relayController.text != relay) {
relayServerMsg = await validateAsync(relayController.text);
if (relayServerMsg != null) return false;
relay = relayController.text;
}
if (apiController.text != relay) {
apiServerMsg = await validateAsync(apiController.text);
if (apiServerMsg != null) return false;
api = apiController.text;
}
return true;
}
return CustomAlertDialog(
title: Text(translate('ID/Relay Server')),
content: Form(
key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
initialValue: id,
controller: idController,
decoration: InputDecoration(
labelText: translate('ID Server'),
),
validator: validate,
onSaved: (String? value) {
if (value != null) id = value.trim();
},
labelText: translate('ID Server'),
errorText: idServerMsg),
)
] +
(isAndroid
? [
TextFormField(
initialValue: relay,
controller: relayController,
decoration: InputDecoration(
labelText: translate('Relay Server'),
),
validator: validate,
onSaved: (String? value) {
if (value != null) relay = value.trim();
},
labelText: translate('Relay Server'),
errorText: relayServerMsg),
)
]
: []) +
[
TextFormField(
initialValue: api,
controller: apiController,
decoration: InputDecoration(
labelText: translate('API Server'),
),
validator: validate,
onSaved: (String? value) {
if (value != null) api = value.trim();
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (v) {
if (v != null && v.length > 0) {
if (!(v.startsWith('http://') ||
v.startsWith("https://"))) {
return translate("invalid_http");
}
}
return apiServerMsg;
},
),
TextFormField(
@@ -208,11 +234,13 @@ void showServerSettingsWithValue(
decoration: InputDecoration(
labelText: 'Key',
),
validator: null,
onSaved: (String? value) {
onChanged: (String? value) {
if (value != null) key = value.trim();
},
),
Offstage(
offstage: !isInProgress,
child: LinearProgressIndicator())
])),
actions: [
TextButton(
@@ -224,24 +252,28 @@ void showServerSettingsWithValue(
),
TextButton(
style: flatButtonStyle,
onPressed: () {
if (formKey.currentState != null &&
formKey.currentState!.validate()) {
formKey.currentState!.save();
if (id != id0)
gFFI.setByName('option',
'{"name": "custom-rendezvous-server", "value": "$id"}');
onPressed: () async {
setState(() {
idServerMsg = null;
relayServerMsg = null;
apiServerMsg = null;
isInProgress = true;
});
if (await validate()) {
if (id != id0) {
bind.mainSetOption(key: "custom-rendezvous-server", value: id);
}
if (relay != relay0)
gFFI.setByName(
'option', '{"name": "relay-server", "value": "$relay"}');
if (key != key0)
gFFI.setByName('option', '{"name": "key", "value": "$key"}');
bind.mainSetOption(key: "relay-server", value: relay);
if (key != key0) bind.mainSetOption(key: "key", value: key);
if (api != api0)
gFFI.setByName(
'option', '{"name": "api-server", "value": "$api"}');
bind.mainSetOption(key: "api-server", value: api);
gFFI.ffiModel.updateUser();
close();
}
setState(() {
isInProgress = false;
});
},
child: Text(translate('OK')),
),
@@ -250,11 +282,11 @@ void showServerSettingsWithValue(
});
}
String? validate(value) {
Future<String?> validateAsync(String value) async {
value = value.trim();
if (value.isEmpty) {
return null;
}
final res = gFFI.getByName('test_if_valid_server', value);
final res = await bind.mainTestIfValidServer(server: value);
return res.isEmpty ? null : res;
}

View File

@@ -185,11 +185,12 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
}
}
void showServerSettings() {
final id = gFFI.getByName('option', 'custom-rendezvous-server');
final relay = gFFI.getByName('option', 'relay-server');
final api = gFFI.getByName('option', 'api-server');
final key = gFFI.getByName('option', 'key');
void showServerSettings() async {
Map<String, dynamic> options = jsonDecode(await bind.mainGetOptions());
String id = options['custom-rendezvous-server'] ?? "";
String relay = options['relay-server'] ?? "";
String api = options['api-server'] ?? "";
String key = options['key'] ?? "";
showServerSettingsWithValue(id, relay, key, api);
}

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:dash_chat_2/dash_chat_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import '../../mobile/widgets/overlay.dart';
import 'model.dart';
@@ -72,7 +73,7 @@ class ChatModel with ChangeNotifier {
}
}
receive(int id, String text) {
receive(int id, String text) async {
if (text.isEmpty) return;
// first message show overlay icon
if (chatIconOverlayEntry == null) {
@@ -82,7 +83,7 @@ class ChatModel with ChangeNotifier {
if (id == clientModeID) {
chatUser = ChatUser(
firstName: _ffi.target?.ffiModel.pi.username,
id: _ffi.target?.getId() ?? "",
id: await bind.mainGetLastRemoteId(),
);
} else {
final client = _ffi.target?.serverModel.clients[id];

View File

@@ -444,7 +444,7 @@ class FileModel extends ChangeNotifier {
items.items.forEach((from) async {
_jobId++;
await bind.sessionSendFiles(
id: '${_ffi.target?.getId()}',
id: await bind.mainGetLastRemoteId(),
actId: _jobId,
path: from.path,
to: PathUtil.join(toPath, from.name, isWindows),

View File

@@ -881,11 +881,6 @@ class FFI {
this.qualityMonitorModel = QualityMonitorModel(WeakReference(this));
}
/// Get the remote id for current client.
String getId() {
return getByName('remote_id'); // TODO
}
/// Send a mouse tap event(down and up).
void tap(MouseButtons button) {
sendMouse('down', button);
@@ -963,9 +958,9 @@ class FFI {
}
/// List the saved peers.
List<Peer> peers() {
Future<List<Peer>> peers() async {
try {
var str = getByName('peers'); // TODO
var str = await bind.mainGetRecentPeers();
if (str == "") return [];
List<dynamic> peers = json.decode(str);
return peers
@@ -1046,33 +1041,6 @@ class FFI {
platformFFI.setByName(name, value);
}
String getOption(String name) {
return platformFFI.getByName("option", name);
}
Future<String> getLocalOption(String name) {
return bind.mainGetLocalOption(key: name);
}
Future<void> setLocalOption(String key, String value) {
return bind.mainSetLocalOption(key: key, value: value);
}
Future<String> getPeerOption(String id, String key) {
return bind.mainGetPeerOption(id: id, key: key);
}
Future<void> setPeerOption(String id, String key, String value) {
return bind.mainSetPeerOption(id: id, key: key, value: value);
}
void setOption(String name, String value) {
Map<String, String> res = Map()
..["name"] = name
..["value"] = value;
return platformFFI.setByName('option', jsonEncode(res));
}
handleMouse(Map<String, dynamic> evt, {double tabBarHeight = 0.0}) {
var type = '';
var isMove = false;
@@ -1148,8 +1116,8 @@ class FFI {
return await bind.mainGetSoundInputs();
}
String getDefaultAudioInput() {
final input = getOption('audio-input');
Future<String> getDefaultAudioInput() async {
final input = await bind.mainGetOption(key: 'audio-input');
if (input.isEmpty && Platform.isWindows) {
return "System Sound";
}
@@ -1157,11 +1125,14 @@ class FFI {
}
void setDefaultAudioInput(String input) {
setOption('audio-input', input);
bind.mainSetOption(key: 'audio-input', value: input);
}
Future<Map<String, String>> getHttpHeaders() async {
return {"Authorization": "Bearer " + await getLocalOption("access_token")};
return {
"Authorization":
"Bearer " + await bind.mainGetLocalOption(key: "access_token")
};
}
}
@@ -1233,11 +1204,12 @@ void initializeCursorAndCanvas(FFI ffi) async {
/// 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);
}
// 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

@@ -29,6 +29,7 @@ typedef HandleEvent = void Function(Map<String, dynamic> evt);
class PlatformFFI {
String _dir = '';
String _homeDir = '';
F2? _translate;
F2? _getByName;
F3? _setByName;
var _eventHandlers = Map<String, Map<String, HandleEvent>>();
@@ -75,6 +76,19 @@ class PlatformFFI {
}
}
String translate(String name, String locale) {
if (_translate == null) return '';
var a = name.toNativeUtf8();
var b = locale.toNativeUtf8();
var p = _translate!(a, b);
assert(p != nullptr);
final res = p.toDartString();
calloc.free(p);
calloc.free(a);
calloc.free(b);
return res;
}
/// Send **get** command to the Rust core based on [name] and [arg].
/// Return the result as a string.
String getByName(String name, [String arg = '']) {
@@ -118,6 +132,7 @@ class PlatformFFI {
: DynamicLibrary.process();
debugPrint('initializing FFI ${_appType}');
try {
_translate = dylib.lookupFunction<F2, F2>('translate');
_getByName = dylib.lookupFunction<F2, F2>('get_by_name');
_setByName =
dylib.lookupFunction<Void Function(Pointer<Utf8>, Pointer<Utf8>), F3>(

View File

@@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/models/platform_model.dart';
import 'package:wakelock/wakelock.dart';
import '../common.dart';
@@ -57,7 +58,7 @@ class ServerModel with ChangeNotifier {
set verificationMethod(String method) {
_verificationMethod = method;
gFFI.setOption("verification-method", method);
bind.mainSetOption(key: "verification-method", value: method);
}
String get temporaryPasswordLength {
@@ -70,7 +71,7 @@ class ServerModel with ChangeNotifier {
set temporaryPasswordLength(String length) {
_temporaryPasswordLength = length;
gFFI.setOption("temporary-password-length", length);
bind.mainSetOption(key: "temporary-password-length", value: length);
}
TextEditingController get serverId => _serverId;
@@ -85,7 +86,7 @@ class ServerModel with ChangeNotifier {
ServerModel(this.parent) {
() async {
_emptyIdShow = translate("Generating ...", ffi: this.parent.target);
_emptyIdShow = translate("Generating ...");
_serverId = TextEditingController(text: this._emptyIdShow);
/**
* 1. check android permission
@@ -153,11 +154,13 @@ class ServerModel with ChangeNotifier {
});
}
updatePasswordModel() {
updatePasswordModel() async {
var update = false;
final temporaryPassword = gFFI.getByName("temporary_password");
final verificationMethod = gFFI.getOption("verification-method");
final temporaryPasswordLength = gFFI.getOption("temporary-password-length");
final verificationMethod =
await bind.mainGetOption(key: "verification-method");
final temporaryPasswordLength =
await bind.mainGetOption(key: "temporary-password-length");
final oldPwdText = _serverPasswd.text;
if (_serverPasswd.text != temporaryPassword) {
_serverPasswd.text = temporaryPassword;
@@ -325,7 +328,7 @@ class ServerModel with ChangeNotifier {
const maxCount = 10;
while (count < maxCount) {
await Future.delayed(Duration(seconds: 1));
final id = parent.target?.getByName("server_id") ?? "";
final id = await bind.mainGetMyId();
if (id.isEmpty) {
continue;
} else {

View File

@@ -1,8 +1,9 @@
import 'dart:io';
import 'package:flutter_hbb/models/model.dart';
import 'package:tray_manager/tray_manager.dart';
import '../common.dart';
Future<void> initTray({List<MenuItem>? extra_item}) async {
List<MenuItem> items = [
MenuItem(key: "show", label: translate("show rustdesk")),