flutter_desktop: fix global envet stream shading && refactor platform ffi

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou
2022-08-03 22:03:31 +08:00
parent d3bc0ca073
commit 7a2de5d280
20 changed files with 476 additions and 398 deletions

View File

@@ -16,6 +16,7 @@ import '../../mobile/pages/home_page.dart';
import '../../mobile/pages/scan_page.dart';
import '../../mobile/pages/settings_page.dart';
import '../../models/model.dart';
import '../../models/platform_model.dart';
// enum RemoteType { recently, favorite, discovered, addressBook }
@@ -428,10 +429,10 @@ class _ConnectionPageState extends State<ConnectionPage> {
updateStatus() async {
svcStopped.value = gFFI.getOption("stop-service") == "Y";
final status = jsonDecode(await gFFI.bind.mainGetConnectStatus())
as Map<String, dynamic>;
final status =
jsonDecode(await bind.mainGetConnectStatus()) as Map<String, dynamic>;
svcStatusCode.value = status["status_num"];
svcIsUsingPublicServer.value = await gFFI.bind.mainIsUsingPublicServer();
svcIsUsingPublicServer.value = await bind.mainIsUsingPublicServer();
}
handleLogin() {
@@ -906,13 +907,13 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage>
if (_tabController.indexIsChanging) {
switch (_tabController.index) {
case 0:
gFFI.bind.mainLoadRecentPeers();
bind.mainLoadRecentPeers();
break;
case 1:
gFFI.bind.mainLoadFavPeers();
bind.mainLoadFavPeers();
break;
case 2:
gFFI.bind.mainDiscover();
bind.mainDiscover();
break;
case 3:
break;

View File

@@ -8,6 +8,7 @@ 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';
import 'package:provider/provider.dart';
@@ -630,13 +631,13 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
setState(() {
msg = "";
isInProgress = true;
gFFI.bind.mainChangeId(newId: newId);
bind.mainChangeId(newId: newId);
});
var status = await gFFI.bind.mainGetAsyncStatus();
var status = await bind.mainGetAsyncStatus();
while (status == " ") {
await Future.delayed(Duration(milliseconds: 100));
status = await gFFI.bind.mainGetAsyncStatus();
status = await bind.mainGetAsyncStatus();
}
if (status.isEmpty) {
// ok
@@ -655,8 +656,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
}
void changeServer() async {
Map<String, dynamic> oldOptions =
jsonDecode(await gFFI.bind.mainGetOptions());
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
print("${oldOptions}");
String idServer = oldOptions['custom-rendezvous-server'] ?? "";
var idServerMsg = "";
@@ -814,7 +814,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
if (idServer.isNotEmpty) {
idServerMsg = translate(
await gFFI.bind.mainTestIfValidServer(server: idServer));
await bind.mainTestIfValidServer(server: idServer));
if (idServerMsg.isEmpty) {
oldOptions['custom-rendezvous-server'] = idServer;
} else {
@@ -826,8 +826,8 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
}
if (relayServer.isNotEmpty) {
relayServerMsg = translate(await gFFI.bind
.mainTestIfValidServer(server: relayServer));
relayServerMsg = translate(
await bind.mainTestIfValidServer(server: relayServer));
if (relayServerMsg.isEmpty) {
oldOptions['relay-server'] = relayServer;
} else {
@@ -853,7 +853,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
}
// ok
oldOptions['key'] = key;
await gFFI.bind.mainSetOptions(json: jsonEncode(oldOptions));
await bind.mainSetOptions(json: jsonEncode(oldOptions));
close();
},
child: Text(translate("OK"))),
@@ -863,8 +863,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
}
void changeWhiteList() async {
Map<String, dynamic> oldOptions =
jsonDecode(await gFFI.bind.mainGetOptions());
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
var newWhiteList = ((oldOptions['whitelist'] ?? "") as String).split(',');
var newWhiteListField = newWhiteList.join('\n');
var msg = "";
@@ -935,7 +934,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
newWhiteList = ips.join(',');
}
oldOptions['whitelist'] = newWhiteList;
await gFFI.bind.mainSetOptions(json: jsonEncode(oldOptions));
await bind.mainSetOptions(json: jsonEncode(oldOptions));
close();
},
child: Text(translate("OK"))),
@@ -945,7 +944,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
}
void changeSocks5Proxy() async {
var socks = await gFFI.bind.mainGetSocks();
var socks = await bind.mainGetSocks();
String proxy = "";
String proxyMsg = "";
@@ -1072,7 +1071,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
if (proxy.isNotEmpty) {
proxyMsg = translate(
await gFFI.bind.mainTestIfValidServer(server: proxy));
await bind.mainTestIfValidServer(server: proxy));
if (proxyMsg.isEmpty) {
// ignore
} else {
@@ -1080,7 +1079,7 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
return;
}
}
await gFFI.bind.mainSetSocks(
await bind.mainSetSocks(
proxy: proxy, username: username, password: password);
close();
},
@@ -1091,9 +1090,9 @@ class _DesktopHomePageState extends State<DesktopHomePage> with TrayListener {
}
void about() async {
final appName = await gFFI.bind.mainGetAppName();
final license = await gFFI.bind.mainGetLicense();
final version = await gFFI.bind.mainGetVersion();
final appName = await bind.mainGetAppName();
final license = await bind.mainGetLicense();
final version = await bind.mainGetVersion();
final linkStyle = TextStyle(decoration: TextDecoration.underline);
DialogManager.show((setState, close) {
return CustomAlertDialog(

View File

@@ -11,6 +11,7 @@ import 'package:wakelock/wakelock.dart';
import '../../common.dart';
import '../../models/model.dart';
import '../../models/platform_model.dart';
class FileManagerPage extends StatefulWidget {
FileManagerPage({Key? key, required this.id}) : super(key: key);
@@ -37,7 +38,7 @@ class _FileManagerPageState extends State<FileManagerPage>
@override
void initState() {
super.initState();
Get.put(FFI.newFFI()..connect(widget.id, isFileTransfer: true),
Get.put(FFI()..connect(widget.id, isFileTransfer: true),
tag: 'ft_${widget.id}');
// _ffi.ffiModel.updateEventListener(widget.id);
if (!Platform.isLinux) {
@@ -464,13 +465,15 @@ class _FileManagerPageState extends State<FileManagerPage>
decoration: BoxDecoration(color: Colors.blue),
padding: EdgeInsets.all(8.0),
child: FutureBuilder<String>(
future: _ffi.bind.sessionGetPlatform(
future: bind.sessionGetPlatform(
id: _ffi.id, isRemote: !isLocal),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
return getPlatformImage('${snapshot.data}');
} else {
return CircularProgressIndicator(color: Colors.white,);
return CircularProgressIndicator(
color: Colors.white,
);
}
})),
Text(isLocal
@@ -505,21 +508,25 @@ class _FileManagerPageState extends State<FileManagerPage>
border: Border.all(color: Colors.black12)),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
isDense: true,
prefix: Padding(padding: EdgeInsets.only(left: 4.0)),
suffix: DropdownButton<String>(
isDense: true,
underline: Offstage(),
items: [
// TODO: favourite
DropdownMenuItem(child: Text('/'), value: '/',)
], onChanged: (path) {
if (path is String && path.isNotEmpty){
model.openDirectory(path, isLocal: isLocal);
}
})
),
border: InputBorder.none,
isDense: true,
prefix:
Padding(padding: EdgeInsets.only(left: 4.0)),
suffix: DropdownButton<String>(
isDense: true,
underline: Offstage(),
items: [
// TODO: favourite
DropdownMenuItem(
child: Text('/'),
value: '/',
)
],
onChanged: (path) {
if (path is String && path.isNotEmpty) {
model.openDirectory(path, isLocal: isLocal);
}
})),
controller: TextEditingController(
text: isLocal
? model.currentLocalDir.path

View File

@@ -16,10 +16,10 @@ import 'package:wakelock/wakelock.dart';
// import 'package:window_manager/window_manager.dart';
import '../../common.dart';
import '../../consts.dart';
import '../../mobile/widgets/dialog.dart';
import '../../mobile/widgets/overlay.dart';
import '../../models/model.dart';
import '../../models/platform_model.dart';
final initText = '\1' * 1024;
@@ -59,8 +59,6 @@ class _RemotePageState extends State<RemotePage>
var ffitmp = FFI();
ffitmp.canvasModel.tabBarHeight = super.widget.tabBarHeight;
final ffi = Get.put(ffitmp, tag: widget.id);
// note: a little trick
ffi.ffiModel.platformFFI = gFFI.ffiModel.platformFFI;
ffi.connect(widget.id, tabBarHeight: super.widget.tabBarHeight);
WidgetsBinding.instance.addPostFrameCallback((_) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
@@ -157,7 +155,7 @@ class _RemotePageState extends State<RemotePage>
if (newValue.length > common) {
var s = newValue.substring(common);
if (s.length > 1) {
_ffi.bind.sessionInputString(id: widget.id, value: s);
bind.sessionInputString(id: widget.id, value: s);
} else {
inputChar(s);
}
@@ -191,11 +189,11 @@ class _RemotePageState extends State<RemotePage>
content == '' ||
content == '【】')) {
// can not only input content[0], because when input ], [ are also auo insert, which cause ] never be input
_ffi.bind.sessionInputString(id: widget.id, value: content);
bind.sessionInputString(id: widget.id, value: content);
openKeyboard();
return;
}
_ffi.bind.sessionInputString(id: widget.id, value: content);
bind.sessionInputString(id: widget.id, value: content);
} else {
inputChar(content);
}
@@ -509,8 +507,8 @@ class _RemotePageState extends State<RemotePage>
id: widget.id,
)
];
final cursor = _ffi.bind
.getSessionToggleOptionSync(id: widget.id, arg: 'show-remote-cursor');
final cursor = bind.getSessionToggleOptionSync(
id: widget.id, arg: 'show-remote-cursor');
if (keyboard || cursor) {
paints.add(CursorPaint(
id: widget.id,
@@ -519,10 +517,10 @@ class _RemotePageState extends State<RemotePage>
paints.add(getHelpTools());
return MouseRegion(
onEnter: (evt) {
_ffi.bind.hostStopSystemKeyPropagate(stopped: false);
bind.hostStopSystemKeyPropagate(stopped: false);
},
onExit: (evt) {
_ffi.bind.hostStopSystemKeyPropagate(stopped: true);
bind.hostStopSystemKeyPropagate(stopped: true);
},
child: Container(
color: MyTheme.canvasColor,
@@ -601,7 +599,7 @@ class _RemotePageState extends State<RemotePage>
more.add(PopupMenuItem<String>(
child: Text(translate('Insert Lock')), value: 'lock'));
if (pi.platform == 'Windows' &&
await _ffi.bind.getSessionToggleOption(id: id, arg: 'privacy-mode') !=
await bind.getSessionToggleOption(id: id, arg: 'privacy-mode') !=
true) {
more.add(PopupMenuItem<String>(
child: Text(translate((_ffi.ffiModel.inputBlocked ? 'Unb' : 'B') +
@@ -617,28 +615,27 @@ class _RemotePageState extends State<RemotePage>
elevation: 8,
);
if (value == 'cad') {
_ffi.bind.sessionCtrlAltDel(id: widget.id);
bind.sessionCtrlAltDel(id: widget.id);
} else if (value == 'lock') {
_ffi.bind.sessionLockScreen(id: widget.id);
bind.sessionLockScreen(id: widget.id);
} else if (value == 'block-input') {
_ffi.bind.sessionToggleOption(
bind.sessionToggleOption(
id: widget.id,
value: (_ffi.ffiModel.inputBlocked ? 'un' : '') + 'block-input');
_ffi.ffiModel.inputBlocked = !_ffi.ffiModel.inputBlocked;
} else if (value == 'refresh') {
_ffi.bind.sessionRefresh(id: widget.id);
bind.sessionRefresh(id: widget.id);
} else if (value == 'paste') {
() async {
ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
if (data != null && data.text != null) {
_ffi.bind.sessionInputString(id: widget.id, value: data.text ?? "");
bind.sessionInputString(id: widget.id, value: data.text ?? "");
}
}();
} else if (value == 'enter_os_password') {
var password =
await _ffi.bind.getSessionOption(id: id, arg: "os-password");
var password = await bind.getSessionOption(id: id, arg: "os-password");
if (password != null) {
_ffi.bind.sessionInputOsPassword(id: widget.id, value: password);
bind.sessionInputOsPassword(id: widget.id, value: password);
} else {
showSetOSPassword(widget.id, true);
}
@@ -666,7 +663,7 @@ class _RemotePageState extends State<RemotePage>
onTouchModeChange: (t) {
_ffi.ffiModel.toggleTouchMode();
final v = _ffi.ffiModel.touchMode ? 'Y' : '';
_ffi.bind.sessionPeerOption(
bind.sessionPeerOption(
id: widget.id, name: "touch-mode", value: v);
}));
}));
@@ -892,12 +889,12 @@ class ImagePainter extends CustomPainter {
CheckboxListTile getToggle(
String id, void Function(void Function()) setState, option, name) {
final opt = ffi(id).bind.getSessionToggleOptionSync(id: id, arg: option);
final opt = bind.getSessionToggleOptionSync(id: id, arg: option);
return CheckboxListTile(
value: opt,
onChanged: (v) {
setState(() {
ffi(id).bind.sessionToggleOption(id: id, value: option);
bind.sessionToggleOption(id: id, value: option);
});
},
dense: true,
@@ -917,11 +914,10 @@ RadioListTile<String> getRadio(String name, String toValue, String curValue,
}
void showOptions(String id) async {
String quality =
await ffi(id).bind.getSessionImageQuality(id: id) ?? 'balanced';
String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced';
if (quality == '') quality = 'balanced';
String viewStyle =
await ffi(id).bind.getSessionOption(id: id, arg: 'view-style') ?? '';
await bind.getSessionOption(id: id, arg: 'view-style') ?? '';
var displays = <Widget>[];
final pi = ffi(id).ffiModel.pi;
final image = ffi(id).ffiModel.getConnectionImage();
@@ -934,7 +930,7 @@ void showOptions(String id) async {
children.add(InkWell(
onTap: () {
if (i == cur) return;
ffi(id).bind.sessionSwitchDisplay(id: id, value: i);
bind.sessionSwitchDisplay(id: id, value: i);
SmartDialog.dismiss();
},
child: Ink(
@@ -979,16 +975,14 @@ void showOptions(String id) async {
if (value == null) return;
setState(() {
quality = value;
ffi(id).bind.sessionSetImageQuality(id: id, value: value);
bind.sessionSetImageQuality(id: id, value: value);
});
};
var setViewStyle = (String? value) {
if (value == null) return;
setState(() {
viewStyle = value;
ffi(id)
.bind
.sessionPeerOption(id: id, name: "view-style", value: value);
bind.sessionPeerOption(id: id, name: "view-style", value: value);
ffi(id).canvasModel.updateViewStyle();
});
};
@@ -1018,10 +1012,8 @@ void showOptions(String id) async {
void showSetOSPassword(String id, bool login) async {
final controller = TextEditingController();
var password =
await ffi(id).bind.getSessionOption(id: id, arg: "os-password") ?? "";
var autoLogin =
await ffi(id).bind.getSessionOption(id: id, arg: "auto-login") != "";
var password = await bind.getSessionOption(id: id, arg: "os-password") ?? "";
var autoLogin = await bind.getSessionOption(id: id, arg: "auto-login") != "";
controller.text = password;
DialogManager.show((setState, close) {
return CustomAlertDialog(
@@ -1054,13 +1046,11 @@ void showSetOSPassword(String id, bool login) async {
style: flatButtonStyle,
onPressed: () {
var text = controller.text.trim();
ffi(id)
.bind
.sessionPeerOption(id: id, name: "os-password", value: text);
ffi(id).bind.sessionPeerOption(
bind.sessionPeerOption(id: id, name: "os-password", value: text);
bind.sessionPeerOption(
id: id, name: "auto-login", value: autoLogin ? 'Y' : '');
if (text != "" && login) {
ffi(id).bind.sessionInputOsPassword(id: id, value: text);
bind.sessionInputOsPassword(id: id, value: text);
}
close();
},

View File

@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
@@ -8,6 +7,7 @@ import 'package:visibility_detector/visibility_detector.dart';
import 'package:window_manager/window_manager.dart';
import '../../models/peer_model.dart';
import '../../models/platform_model.dart';
import '../../common.dart';
import 'peercard_widget.dart';
@@ -116,7 +116,7 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener {
if (!setEquals(_curPeers, _lastQueryPeers)) {
if (now.difference(_lastChangeTime) > Duration(seconds: 1)) {
if (_curPeers.length > 0) {
gFFI.ffiModel.platformFFI.ffiBind
platformFFI.ffiBind
.queryOnlines(ids: _curPeers.toList(growable: false));
_lastQueryPeers = {..._curPeers};
_lastQueryTime = DateTime.now();
@@ -127,7 +127,7 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener {
if (_queryCoun < _maxQueryCount) {
if (now.difference(_lastQueryTime) > Duration(seconds: 20)) {
if (_curPeers.length > 0) {
gFFI.ffiModel.platformFFI.ffiBind
platformFFI.ffiBind
.queryOnlines(ids: _curPeers.toList(growable: false));
_lastQueryTime = DateTime.now();
_queryCoun += 1;
@@ -169,7 +169,7 @@ class RecentPeerWidget extends BasePeerWidget {
@override
Widget build(BuildContext context) {
final widget = super.build(context);
gFFI.bind.mainLoadRecentPeers();
bind.mainLoadRecentPeers();
return widget;
}
}
@@ -186,7 +186,7 @@ class FavoritePeerWidget extends BasePeerWidget {
@override
Widget build(BuildContext context) {
final widget = super.build(context);
gFFI.bind.mainLoadFavPeers();
bind.mainLoadFavPeers();
return widget;
}
}
@@ -203,7 +203,7 @@ class DiscoveredPeerWidget extends BasePeerWidget {
@override
Widget build(BuildContext context) {
final widget = super.build(context);
gFFI.bind.mainLoadLanPeers();
bind.mainLoadLanPeers();
return widget;
}
}

View File

@@ -5,9 +5,11 @@ import 'package:get/get.dart';
import '../../common.dart';
import '../../models/model.dart';
import '../../models/platform_model.dart';
import '../../models/peer_model.dart';
typedef PopupMenuItemsFunc = Future<List<PopupMenuItem<String>>> Function();
enum PeerType { recent, fav, discovered, ab }
class _PeerCard extends StatefulWidget {
@@ -15,10 +17,11 @@ class _PeerCard extends StatefulWidget {
final PopupMenuItemsFunc popupMenuItemsFunc;
final PeerType type;
_PeerCard({required this.peer,
required this.popupMenuItemsFunc,
Key? key,
required this.type})
_PeerCard(
{required this.peer,
required this.popupMenuItemsFunc,
Key? key,
required this.type})
: super(key: key);
@override
@@ -54,9 +57,10 @@ class _PeerCardState extends State<_PeerCard>
));
}
Widget _buildPeerTile(BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
Widget _buildPeerTile(
BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
return Obx(
() => Container(
() => Container(
decoration: deco.value,
child: Column(
mainAxisSize: MainAxisSize.min,
@@ -135,7 +139,7 @@ class _PeerCardState extends State<_PeerCard>
child: CircleAvatar(
radius: 5,
backgroundColor:
peer.online ? Colors.green : Colors.yellow)),
peer.online ? Colors.green : Colors.yellow)),
Text('${peer.id}')
]),
InkWell(
@@ -183,12 +187,13 @@ class _PeerCardState extends State<_PeerCard>
);
if (value == 'remove') {
setState(() => gFFI.setByName('remove', '$id'));
() async {
() async {
removePreference(id);
}();
} else if (value == 'file') {
_connect(id, isFileTransfer: true);
} else if (value == 'add-fav') {} else if (value == 'connect') {
} else if (value == 'add-fav') {
} else if (value == 'connect') {
_connect(id, isFileTransfer: false);
} else if (value == 'ab-delete') {
gFFI.abModel.deletePeer(id);
@@ -199,7 +204,7 @@ class _PeerCardState extends State<_PeerCard>
} else if (value == 'rename') {
_rename(id);
} else if (value == 'unremember-password') {
await gFFI.bind.mainForgetPassword(id: id);
await bind.mainForgetPassword(id: id);
}
}
@@ -220,7 +225,7 @@ class _PeerCardState extends State<_PeerCard>
child: GestureDetector(
onTap: onTap,
child: Obx(
() => Container(
() => Container(
decoration: BoxDecoration(
color: rxTags.contains(tagName) ? Colors.blue : null,
border: Border.all(color: MyTheme.darkGray),
@@ -264,12 +269,12 @@ class _PeerCardState extends State<_PeerCard>
child: Wrap(
children: tags
.map((e) => _buildTag(e, selectedTag, onTap: () {
if (selectedTag.contains(e)) {
selectedTag.remove(e);
} else {
selectedTag.add(e);
}
}))
if (selectedTag.contains(e)) {
selectedTag.remove(e);
} else {
selectedTag.add(e);
}
}))
.toList(growable: false),
),
),