This commit is contained in:
rustdesk
2023-11-06 20:12:01 +08:00
parent 679a026e72
commit d7e8d4d5c3
64 changed files with 1193 additions and 1082 deletions

View File

@@ -50,6 +50,7 @@ class _ConnectionPageState extends State<ConnectionPage>
return list.sublist(0, n);
}
}
bool isPeersLoading = false;
bool isPeersLoaded = false;
@@ -81,7 +82,7 @@ class _ConnectionPageState extends State<ConnectionPage>
if (Get.isRegistered<IDTextEditingController>()) {
Get.delete<IDTextEditingController>();
}
if (Get.isRegistered<TextEditingController>()){
if (Get.isRegistered<TextEditingController>()) {
Get.delete<TextEditingController>();
}
super.dispose();
@@ -157,9 +158,9 @@ class _ConnectionPageState extends State<ConnectionPage>
await Future.delayed(Duration(milliseconds: 100));
peers = await getAllPeers();
setState(() {
isPeersLoading = false;
isPeersLoaded = true;
});
isPeersLoading = false;
isPeersLoaded = true;
});
}
/// UI for the remote ID TextField.
@@ -177,148 +178,173 @@ class _ConnectionPageState extends State<ConnectionPage>
Row(
children: [
Expanded(
child: AutoSizeText(
translate('Control Remote Desktop'),
maxLines: 1,
style: Theme.of(context)
.textTheme
.titleLarge
?.merge(TextStyle(height: 1)),
),
),
child: Row(
children: [
AutoSizeText(
translate('Control Remote Desktop'),
maxLines: 1,
style: Theme.of(context)
.textTheme
.titleLarge
?.merge(TextStyle(height: 1)),
).marginOnly(right: 4),
Tooltip(
waitDuration: Duration(milliseconds: 0),
message: translate("id_input_tip"),
child: Icon(
Icons.help_outline_outlined,
size: 16,
color: Theme.of(context)
.textTheme
.titleLarge
?.color
?.withOpacity(0.5),
),
),
],
)),
],
).marginOnly(bottom: 15),
Row(
children: [
Expanded(
child:
Autocomplete<Peer>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<Peer>.empty();
}
else if (peers.isEmpty && !isPeersLoaded) {
Peer emptyPeer = Peer(
id: '',
username: '',
hostname: '',
alias: '',
platform: '',
tags: [],
hash: '',
forceAlwaysRelay: false,
rdpPort: '',
rdpUsername: '',
loginName: '',
child: Autocomplete<Peer>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<Peer>.empty();
} else if (peers.isEmpty && !isPeersLoaded) {
Peer emptyPeer = Peer(
id: '',
username: '',
hostname: '',
alias: '',
platform: '',
tags: [],
hash: '',
forceAlwaysRelay: false,
rdpPort: '',
rdpUsername: '',
loginName: '',
);
return [emptyPeer];
} else {
String textWithoutSpaces =
textEditingValue.text.replaceAll(" ", "");
if (int.tryParse(textWithoutSpaces) != null) {
textEditingValue = TextEditingValue(
text: textWithoutSpaces,
selection: textEditingValue.selection,
);
return [emptyPeer];
}
else {
String textWithoutSpaces = textEditingValue.text.replaceAll(" ", "");
if (int.tryParse(textWithoutSpaces) != null) {
textEditingValue = TextEditingValue(
text: textWithoutSpaces,
selection: textEditingValue.selection,
);
}
String textToFind = textEditingValue.text.toLowerCase();
String textToFind = textEditingValue.text.toLowerCase();
return peers.where((peer) =>
peer.id.toLowerCase().contains(textToFind) ||
peer.username.toLowerCase().contains(textToFind) ||
peer.hostname.toLowerCase().contains(textToFind) ||
peer.alias.toLowerCase().contains(textToFind))
.toList();
return peers
.where((peer) =>
peer.id.toLowerCase().contains(textToFind) ||
peer.username
.toLowerCase()
.contains(textToFind) ||
peer.hostname
.toLowerCase()
.contains(textToFind) ||
peer.alias.toLowerCase().contains(textToFind))
.toList();
}
},
fieldViewBuilder: (
BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted,
) {
fieldTextEditingController.text = _idController.text;
Get.put<TextEditingController>(fieldTextEditingController);
fieldFocusNode.addListener(() async {
_idInputFocused.value = fieldFocusNode.hasFocus;
if (fieldFocusNode.hasFocus && !isPeersLoading) {
_fetchPeers();
}
},
});
final textLength =
fieldTextEditingController.value.text.length;
// select all to facilitate removing text, just following the behavior of address input of chrome
fieldTextEditingController.selection =
TextSelection(baseOffset: 0, extentOffset: textLength);
return Obx(() => TextField(
autocorrect: false,
enableSuggestions: false,
keyboardType: TextInputType.visiblePassword,
focusNode: fieldFocusNode,
style: const TextStyle(
fontFamily: 'WorkSans',
fontSize: 22,
height: 1.4,
),
maxLines: 1,
cursorColor:
Theme.of(context).textTheme.titleLarge?.color,
decoration: InputDecoration(
filled: false,
counterText: '',
hintText: _idInputFocused.value
? null
: translate('Enter Remote ID'),
contentPadding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 13)),
controller: fieldTextEditingController,
inputFormatters: [IDTextInputFormatter()],
onChanged: (v) {
_idController.id = v;
},
));
},
onSelected: (option) {
setState(() {
_idController.id = option.id;
FocusScope.of(context).unfocus();
});
},
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Peer> onSelected,
Iterable<Peer> options) {
double maxHeight = options.length * 50;
maxHeight = maxHeight > 200 ? 200 : maxHeight;
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode ,
VoidCallback onFieldSubmitted,
) {
fieldTextEditingController.text = _idController.text;
Get.put<TextEditingController>(fieldTextEditingController);
fieldFocusNode.addListener(() async {
_idInputFocused.value = fieldFocusNode.hasFocus;
if (fieldFocusNode.hasFocus && !isPeersLoading){
_fetchPeers();
}
});
final textLength = fieldTextEditingController.value.text.length;
// select all to facilitate removing text, just following the behavior of address input of chrome
fieldTextEditingController.selection = TextSelection(baseOffset: 0, extentOffset: textLength);
return Obx(() =>
TextField(
maxLength: 90,
autocorrect: false,
enableSuggestions: false,
keyboardType: TextInputType.visiblePassword,
focusNode: fieldFocusNode,
style: const TextStyle(
fontFamily: 'WorkSans',
fontSize: 22,
height: 1.4,
),
maxLines: 1,
cursorColor: Theme.of(context).textTheme.titleLarge?.color,
decoration: InputDecoration(
filled: false,
counterText: '',
hintText: _idInputFocused.value
? null
: translate('Enter Remote ID'),
contentPadding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 13)),
controller: fieldTextEditingController,
inputFormatters: [IDTextInputFormatter()],
onChanged: (v) {
_idController.id = v;
},
));
},
onSelected: (option) {
setState(() {
_idController.id = option.id;
FocusScope.of(context).unfocus();
});
},
optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<Peer> onSelected, Iterable<Peer> options) {
double maxHeight = options.length * 50;
maxHeight = maxHeight > 200 ? 200 : maxHeight;
return Align(
alignment: Alignment.topLeft,
child: ClipRRect(
return Align(
alignment: Alignment.topLeft,
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Material(
elevation: 4,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: maxHeight,
maxWidth: 319,
),
child: peers.isEmpty && isPeersLoading
? Container(
height: 80,
child: Center(
child: CircularProgressIndicator(
strokeWidth: 2,
),
)
)
: Padding(
padding: const EdgeInsets.only(top: 5),
child: ListView(
children: options.map((peer) => AutocompletePeerTile(onSelect: () => onSelected(peer), peer: peer)).toList(),
elevation: 4,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: maxHeight,
maxWidth: 319,
),
child: peers.isEmpty && isPeersLoading
? Container(
height: 80,
child: Center(
child: CircularProgressIndicator(
strokeWidth: 2,
),
))
: Padding(
padding: const EdgeInsets.only(top: 5),
child: ListView(
children: options
.map((peer) => AutocompletePeerTile(
onSelect: () =>
onSelected(peer),
peer: peer))
.toList(),
),
),
),
),
)),
);
},
)
),
)),
);
},
)),
],
),
Padding(
@@ -329,7 +355,7 @@ class _ConnectionPageState extends State<ConnectionPage>
Button(
isOutline: true,
onTap: () => onConnect(isFileTransfer: true),
text: "Transfer File",
text: "Transfer file",
),
const SizedBox(
width: 17,
@@ -382,7 +408,7 @@ class _ConnectionPageState extends State<ConnectionPage>
onTap: () async {
await start_service(true);
},
child: Text(translate("Start Service"),
child: Text(translate("Start service"),
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: em)))