mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
@@ -797,6 +797,7 @@ void showToast(String text, {Duration timeout = const Duration(seconds: 2)}) {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
||||
child: Text(
|
||||
text,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
fontWeight: FontWeight.w300,
|
||||
@@ -1601,7 +1602,8 @@ bool callUniLinksUriHandler(Uri uri) {
|
||||
String? switch_uuid = param["switch_uuid"];
|
||||
String? password = param["password"];
|
||||
Future.delayed(Duration.zero, () {
|
||||
rustDeskWinManager.newRemoteDesktop(peerId, password: password, switch_uuid: switch_uuid);
|
||||
rustDeskWinManager.newRemoteDesktop(peerId,
|
||||
password: password, switch_uuid: switch_uuid);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@@ -2033,3 +2035,12 @@ Widget futureBuilder(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void onCopyFingerprint(String value) {
|
||||
if (value.isNotEmpty) {
|
||||
Clipboard.setData(ClipboardData(text: value));
|
||||
showToast('$value\n${translate("Copied")}');
|
||||
} else {
|
||||
showToast(translate("no fingerprints"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,29 @@ class ConnectionTypeState {
|
||||
Get.find<ConnectionType>(tag: tag(id));
|
||||
}
|
||||
|
||||
class FingerprintState {
|
||||
static String tag(String id) => 'fingerprint_$id';
|
||||
|
||||
static void init(String id) {
|
||||
final key = tag(id);
|
||||
if (!Get.isRegistered(tag: key)) {
|
||||
final RxString state = ''.obs;
|
||||
Get.put(state, tag: key);
|
||||
} else {
|
||||
Get.find<RxString>(tag: key).value = '';
|
||||
}
|
||||
}
|
||||
|
||||
static void delete(String id) {
|
||||
final key = tag(id);
|
||||
if (Get.isRegistered(tag: key)) {
|
||||
Get.delete(tag: key);
|
||||
}
|
||||
}
|
||||
|
||||
static RxString find(String id) => Get.find<RxString>(tag: tag(id));
|
||||
}
|
||||
|
||||
class ShowRemoteCursorState {
|
||||
static String tag(String id) => 'show_remote_cursor_$id';
|
||||
|
||||
@@ -269,6 +292,7 @@ initSharedStates(String id) {
|
||||
KeyboardEnabledState.init(id);
|
||||
ShowRemoteCursorState.init(id);
|
||||
RemoteCursorMovedState.init(id);
|
||||
FingerprintState.init(id);
|
||||
PeerBoolOption.init(id, 'zoom-cursor', () => false);
|
||||
}
|
||||
|
||||
@@ -279,5 +303,6 @@ removeSharedStates(String id) {
|
||||
ShowRemoteCursorState.delete(id);
|
||||
KeyboardEnabledState.delete(id);
|
||||
RemoteCursorMovedState.delete(id);
|
||||
FingerprintState.delete(id);
|
||||
PeerBoolOption.delete(id, 'zoom-cursor');
|
||||
}
|
||||
|
||||
@@ -201,6 +201,13 @@ List<TTextMenu> toolbarControls(BuildContext context, String id, FFI ffi) {
|
||||
),
|
||||
onPressed: () => ffi.recordingModel.toggle()));
|
||||
}
|
||||
// fingerprint
|
||||
if (!isDesktop) {
|
||||
v.add(TTextMenu(
|
||||
child: Text(translate('Copy Fingerprint')),
|
||||
onPressed: () => onCopyFingerprint(FingerprintState.find(id).value),
|
||||
));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -1390,11 +1390,18 @@ class _AboutState extends State<_About> {
|
||||
final license = await bind.mainGetLicense();
|
||||
final version = await bind.mainGetVersion();
|
||||
final buildDate = await bind.mainGetBuildDate();
|
||||
return {'license': license, 'version': version, 'buildDate': buildDate};
|
||||
final fingerprint = await bind.mainGetFingerprint();
|
||||
return {
|
||||
'license': license,
|
||||
'version': version,
|
||||
'buildDate': buildDate,
|
||||
'fingerprint': fingerprint
|
||||
};
|
||||
}(), hasData: (data) {
|
||||
final license = data['license'].toString();
|
||||
final version = data['version'].toString();
|
||||
final buildDate = data['buildDate'].toString();
|
||||
final fingerprint = data['fingerprint'].toString();
|
||||
const linkStyle = TextStyle(decoration: TextDecoration.underline);
|
||||
final scrollController = ScrollController();
|
||||
return DesktopScrollWrapper(
|
||||
@@ -1415,6 +1422,9 @@ class _AboutState extends State<_About> {
|
||||
SelectionArea(
|
||||
child: Text('${translate('Build Date')}: $buildDate')
|
||||
.marginSymmetric(vertical: 4.0)),
|
||||
SelectionArea(
|
||||
child: Text('${translate('Fingerprint')}: $fingerprint')
|
||||
.marginSymmetric(vertical: 4.0)),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
launchUrlString('https://rustdesk.com/privacy');
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:ui' as ui;
|
||||
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
import 'package:flutter_hbb/common/shared_state.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
@@ -158,20 +159,36 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
],
|
||||
);
|
||||
} else {
|
||||
final msgDirect = translate(
|
||||
connectionType.direct.value == ConnectionType.strDirect
|
||||
? 'Direct Connection'
|
||||
: 'Relay Connection');
|
||||
final msgSecure = translate(
|
||||
connectionType.secure.value == ConnectionType.strSecure
|
||||
? 'Secure Connection'
|
||||
: 'Insecure Connection');
|
||||
bool secure =
|
||||
connectionType.secure.value == ConnectionType.strSecure;
|
||||
bool direct =
|
||||
connectionType.direct.value == ConnectionType.strDirect;
|
||||
var msgConn;
|
||||
if (secure && direct) {
|
||||
msgConn = translate("Direct and encrypted connection");
|
||||
} else if (secure && !direct) {
|
||||
msgConn = translate("Relayed and encrypted connection");
|
||||
} else if (!secure && direct) {
|
||||
msgConn = translate("Direct and unencrypted connection");
|
||||
} else {
|
||||
msgConn = translate("Relayed and unencrypted connection");
|
||||
}
|
||||
var msgFingerprint = '${translate('Fingerprint')}:\n';
|
||||
var fingerprint = FingerprintState.find(key).value;
|
||||
if (fingerprint.length > 5 * 8) {
|
||||
var first = fingerprint.substring(0, 39);
|
||||
var second = fingerprint.substring(40);
|
||||
msgFingerprint += '$first\n$second';
|
||||
} else {
|
||||
msgFingerprint += fingerprint;
|
||||
}
|
||||
|
||||
final tab = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
icon,
|
||||
Tooltip(
|
||||
message: '$msgDirect\n$msgSecure',
|
||||
message: '$msgConn\n$msgFingerprint',
|
||||
child: SvgPicture.asset(
|
||||
'assets/${connectionType.secure.value}${connectionType.direct.value}.svg',
|
||||
width: themeConf.iconSize,
|
||||
@@ -285,6 +302,17 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
}
|
||||
}
|
||||
|
||||
menu.add(MenuEntryButton<String>(
|
||||
childBuilder: (TextStyle? style) => Text(
|
||||
translate('Copy Fingerprint'),
|
||||
style: style,
|
||||
),
|
||||
proc: () => onCopyFingerprint(FingerprintState.find(key).value),
|
||||
padding: padding,
|
||||
dismissOnClicked: true,
|
||||
dismissCallback: cancelFunc,
|
||||
));
|
||||
|
||||
return mod_menu.PopupMenu<String>(
|
||||
items: menu
|
||||
.map((entry) => entry.build(
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
@@ -45,6 +46,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
var _autoRecordIncomingSession = false;
|
||||
var _localIP = "";
|
||||
var _directAccessPort = "";
|
||||
var _fingerprint = "";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -135,6 +137,12 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
_directAccessPort = directAccessPort;
|
||||
}
|
||||
|
||||
final fingerprint = await bind.mainGetFingerprint();
|
||||
if (_fingerprint != fingerprint) {
|
||||
update = true;
|
||||
_fingerprint = fingerprint;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
setState(() {});
|
||||
}
|
||||
@@ -462,6 +470,14 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
)),
|
||||
),
|
||||
leading: Icon(Icons.info)),
|
||||
SettingsTile.navigation(
|
||||
onPressed: (context) => onCopyFingerprint(_fingerprint),
|
||||
title: Text(translate("Fingerprint")),
|
||||
value: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(_fingerprint),
|
||||
),
|
||||
leading: Icon(Icons.fingerprint)),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -224,6 +224,8 @@ class FfiModel with ChangeNotifier {
|
||||
parent.target?.chatModel.onVoiceCallIncoming();
|
||||
} else if (name == "update_voice_call_state") {
|
||||
parent.target?.serverModel.updateVoiceCallState(evt);
|
||||
} else if (name == "fingerprint") {
|
||||
FingerprintState.find(peerId).value = evt['fingerprint'] ?? '';
|
||||
} else {
|
||||
debugPrint("Unknown event name: $name");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user