Merge master

This commit is contained in:
csf
2022-08-04 17:24:02 +08:00
parent 07debe8363
commit 3ff2f60fb7
27 changed files with 1015 additions and 281 deletions

View File

@@ -1,4 +1,4 @@
import 'package:dash_chat/dash_chat.dart';
import 'package:dash_chat_2/dash_chat_2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/models/chat_model.dart';
@@ -7,8 +7,6 @@ import 'package:provider/provider.dart';
import '../../models/model.dart';
import 'home_page.dart';
ChatPage chatPage = ChatPage();
class ChatPage extends StatelessWidget implements PageShape {
@override
final title = translate("Chat");
@@ -26,7 +24,7 @@ class ChatPage extends StatelessWidget implements PageShape {
final id = entry.key;
final user = entry.value.chatUser;
return PopupMenuItem<int>(
child: Text("${user.name} ${user.uid}"),
child: Text("${user.firstName} ${user.id}"),
value: id,
);
}).toList();
@@ -47,19 +45,24 @@ class ChatPage extends StatelessWidget implements PageShape {
return Stack(
children: [
DashChat(
inputContainerStyle: BoxDecoration(color: Colors.white70),
sendOnEnter: false,
// if true,reload keyboard everytime,need fix
onSend: (chatMsg) {
chatModel.send(chatMsg);
},
user: chatModel.me,
currentUser: chatModel.me,
messages:
chatModel.messages[chatModel.currentID]?.chatMessages ??
[],
// default scrollToBottom has bug https://github.com/fayeed/dash_chat/issues/53
scrollToBottom: false,
scrollController: chatModel.scroller,
messageOptions: MessageOptions(
showOtherUsersAvatar: false,
showTime: true,
messageDecorationBuilder: (_, __, ___) =>
defaultMessageDecoration(
color: MyTheme.accent80,
borderTopLeft: 8,
borderTopRight: 8,
borderBottomRight: 8,
borderBottomLeft: 8,
)),
),
chatModel.currentID == ChatModel.clientModeID
? SizedBox.shrink()
@@ -71,7 +74,7 @@ class ChatPage extends StatelessWidget implements PageShape {
color: MyTheme.accent80),
SizedBox(width: 5),
Text(
"${currentUser.name ?? ""} ${currentUser.uid ?? ""}",
"${currentUser.firstName} ${currentUser.id}",
style: TextStyle(color: MyTheme.accent50),
),
],

View File

@@ -29,6 +29,7 @@ class _FileManagerPageState extends State<FileManagerPage> {
void initState() {
super.initState();
gFFI.connect(widget.id, isFileTransfer: true);
showLoading(translate('Connecting...'));
gFFI.ffiModel.updateEventListener(widget.id);
Wakelock.enable();
}

View File

@@ -12,6 +12,8 @@ abstract class PageShape extends Widget {
final List<Widget> appBarActions = [];
}
final homeKey = GlobalKey<_HomePageState>();
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
@@ -23,12 +25,23 @@ class _HomePageState extends State<HomePage> {
var _selectedIndex = 0;
final List<PageShape> _pages = [];
void refreshPages() {
setState(() {
initPages();
});
}
@override
void initState() {
super.initState();
initPages();
}
void initPages() {
_pages.clear();
_pages.add(ConnectionPage());
if (isAndroid) {
_pages.addAll([chatPage, ServerPage()]);
_pages.addAll([ChatPage(), ServerPage()]);
}
_pages.add(SettingsPage());
}

View File

@@ -595,6 +595,7 @@ class _RemotePageState extends State<RemotePage> {
child: Stack(children: [
ImagePaint(),
CursorPaint(),
QualityMonitor(),
getHelpTools(),
SizedBox(
width: 0,
@@ -662,7 +663,7 @@ class _RemotePageState extends State<RemotePage> {
more.add(PopupMenuItem<String>(
child: Row(
children: ([
Container(width: 100.0, child: Text(translate('OS Password'))),
Text(translate('OS Password')),
TextButton(
style: flatButtonStyle,
onPressed: () {
@@ -697,6 +698,13 @@ class _RemotePageState extends State<RemotePage> {
value: 'block-input'));
}
}
if (gFFI.ffiModel.permissions["restart"] != false &&
(pi.platform == "Linux" ||
pi.platform == "Windows" ||
pi.platform == "Mac OS")) {
more.add(PopupMenuItem<String>(
child: Text(translate('Restart Remote Device')), value: 'restart'));
}
() async {
var value = await showMenu(
context: context,
@@ -730,6 +738,8 @@ class _RemotePageState extends State<RemotePage> {
}
} else if (value == 'reset_canvas') {
gFFI.cursorModel.reset();
} else if (value == 'restart') {
showRestartRemoteDevice(pi, widget.id);
}
}();
}
@@ -952,6 +962,47 @@ class ImagePainter extends CustomPainter {
}
}
class QualityMonitor extends StatelessWidget {
@override
Widget build(BuildContext context) => ChangeNotifierProvider.value(
value: gFFI.qualityMonitorModel,
child: Consumer<QualityMonitorModel>(
builder: (context, qualityMonitorModel, child) => Positioned(
top: 10,
right: 10,
child: qualityMonitorModel.show
? Container(
padding: EdgeInsets.all(8),
color: MyTheme.canvasColor.withAlpha(120),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Speed: ${qualityMonitorModel.data.speed}",
style: TextStyle(color: MyTheme.grayBg),
),
Text(
"FPS: ${qualityMonitorModel.data.fps}",
style: TextStyle(color: MyTheme.grayBg),
),
Text(
"Delay: ${qualityMonitorModel.data.delay} ms",
style: TextStyle(color: MyTheme.grayBg),
),
Text(
"Target Bitrate: ${qualityMonitorModel.data.targetBitrate}kb",
style: TextStyle(color: MyTheme.grayBg),
),
Text(
"Codec: ${qualityMonitorModel.data.codecFormat}",
style: TextStyle(color: MyTheme.grayBg),
),
],
),
)
: SizedBox.shrink())));
}
CheckboxListTile getToggle(
void Function(void Function()) setState, option, name) {
return CheckboxListTile(
@@ -960,6 +1011,9 @@ CheckboxListTile getToggle(
setState(() {
gFFI.setByName('toggle_option', option);
});
if (option == "show-quality-monitor") {
gFFI.qualityMonitorModel.checkShowQualityMonitor();
}
},
dense: true,
title: Text(translate(name)));
@@ -1062,6 +1116,27 @@ void showOptions() {
}, clickMaskDismiss: true, backDismiss: true);
}
void showRestartRemoteDevice(PeerInfo pi, String id) async {
final res =
await DialogManager.show<bool>((setState, close) => CustomAlertDialog(
title: Row(children: [
Icon(Icons.warning_amber_sharp,
color: Colors.redAccent, size: 28),
SizedBox(width: 10),
Text(translate("Restart Remote Device")),
]),
content: Text(
"${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"),
actions: [
TextButton(
onPressed: () => close(), child: Text(translate("Cancel"))),
ElevatedButton(
onPressed: () => close(true), child: Text(translate("OK"))),
],
));
if (res == true) gFFI.setByName('restart_remote_device');
}
void showSetOSPassword(bool login) {
final controller = TextEditingController();
var password = gFFI.getByName('peer_option', "os-password");

View File

@@ -200,7 +200,8 @@ class ServerInfo extends StatelessWidget {
Icon(Icons.warning_amber_sharp,
color: Colors.redAccent, size: 24),
SizedBox(width: 10),
Text(
Expanded(
child: Text(
translate("Service is not running"),
style: TextStyle(
fontFamily: 'WorkSans',
@@ -208,7 +209,7 @@ class ServerInfo extends StatelessWidget {
fontSize: 18,
color: MyTheme.accent80,
),
)
))
],
)),
SizedBox(height: 5),
@@ -316,30 +317,35 @@ class PermissionRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
SizedBox(
width: 140,
Expanded(
flex: 5,
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(name,
style: TextStyle(fontSize: 16.0, color: MyTheme.accent50))),
SizedBox(
width: 50,
style:
TextStyle(fontSize: 16.0, color: MyTheme.accent50)))),
Expanded(
flex: 2,
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(isOk ? translate("ON") : translate("OFF"),
style: TextStyle(
fontSize: 16.0,
color: isOk ? Colors.green : Colors.grey)),
)
],
color: isOk ? Colors.green : Colors.grey))),
),
TextButton(
onPressed: onPressed,
child: Text(
translate(isOk ? "CLOSE" : "OPEN"),
style: TextStyle(fontWeight: FontWeight.bold),
)),
const Divider(height: 0)
Expanded(
flex: 3,
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerRight,
child: TextButton(
onPressed: onPressed,
child: Text(
translate(isOk ? "CLOSE" : "OPEN"),
style: TextStyle(fontWeight: FontWeight.bold),
)))),
],
);
}

View File

@@ -27,11 +27,11 @@ class SettingsPage extends StatefulWidget implements PageShape {
_SettingsState createState() => _SettingsState();
}
class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
static const url = 'https://rustdesk.com/';
final _hasIgnoreBattery = androidVersion >= 26;
var _ignoreBatteryOpt = false;
const url = 'https://rustdesk.com/';
final _hasIgnoreBattery = androidVersion >= 26;
var _ignoreBatteryOpt = false;
class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
@@ -147,6 +147,12 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
leading: Icon(Icons.cloud),
onPressed: (context) {
showServerSettings();
}),
SettingsTile.navigation(
title: Text(translate('Language')),
leading: Icon(Icons.translate),
onPressed: (context) {
showLanguageSettings();
})
]),
SettingsSection(
@@ -186,6 +192,42 @@ void showServerSettings() {
showServerSettingsWithValue(id, relay, key, api);
}
void showLanguageSettings() {
try {
final langs = json.decode(gFFI.getByName('langs')) as List<dynamic>;
var lang = gFFI.getByName('local_option', 'lang');
DialogManager.show((setState, close) {
final setLang = (v) {
if (lang != v) {
setState(() {
lang = v;
});
final msg = Map()
..['name'] = 'lang'
..['value'] = v;
gFFI.setByName('local_option', json.encode(msg));
homeKey.currentState?.refreshPages();
Future.delayed(Duration(milliseconds: 200), close);
}
};
return CustomAlertDialog(
title: SizedBox.shrink(),
content: Column(
children: [
getRadio('Default', '', lang, setLang),
Divider(color: MyTheme.border),
] +
langs.map((e) {
final key = e[0] as String;
final name = e[1] as String;
return getRadio(name, key, lang, setLang);
}).toList(),
),
actions: []);
}, backDismiss: true, clickMaskDismiss: true);
} catch (_e) {}
}
void showAbout() {
DialogManager.show((setState, close) {
return CustomAlertDialog(

View File

@@ -27,7 +27,7 @@ class DraggableChatWindow extends StatelessWidget {
height: height,
builder: (_, onPanUpdate) {
return isIOS
? chatPage
? ChatPage()
: Scaffold(
resizeToAvoidBottomInset: false,
appBar: CustomAppBar(
@@ -68,7 +68,7 @@ class DraggableChatWindow extends StatelessWidget {
),
),
),
body: chatPage,
body: ChatPage(),
);
});
}