new dialog impl based on Overlay

This commit is contained in:
csf
2022-08-12 18:42:02 +08:00
parent 2e9a6ed4f6
commit e6329dc7eb
22 changed files with 526 additions and 476 deletions

View File

@@ -380,16 +380,16 @@ class _WebMenuState extends State<WebMenu> {
},
onSelected: (value) {
if (value == 'server') {
showServerSettings();
showServerSettings(gFFI.dialogManager);
}
if (value == 'about') {
showAbout();
showAbout(gFFI.dialogManager);
}
if (value == 'login') {
if (username == null) {
showLogin();
showLogin(gFFI.dialogManager);
} else {
logout();
logout(gFFI.dialogManager);
}
}
if (value == 'scan') {

View File

@@ -3,13 +3,11 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
import 'package:flutter_hbb/models/file_model.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:provider/provider.dart';
import 'package:toggle_switch/toggle_switch.dart';
import 'package:wakelock/wakelock.dart';
import '../../common.dart';
import '../../models/model.dart';
import '../widgets/dialog.dart';
class FileManagerPage extends StatefulWidget {
@@ -29,7 +27,10 @@ class _FileManagerPageState extends State<FileManagerPage> {
void initState() {
super.initState();
gFFI.connect(widget.id, isFileTransfer: true);
showLoading(translate('Connecting...'));
WidgetsBinding.instance.addPostFrameCallback((_) {
gFFI.dialogManager
.showLoading(translate('Connecting...'), cancelToClose: true);
});
gFFI.ffiModel.updateEventListener(widget.id);
Wakelock.enable();
}
@@ -38,7 +39,7 @@ class _FileManagerPageState extends State<FileManagerPage> {
void dispose() {
model.onClose();
gFFI.close();
SmartDialog.dismiss();
gFFI.dialogManager.dismissAll();
Wakelock.disable();
super.dispose();
}
@@ -60,7 +61,9 @@ class _FileManagerPageState extends State<FileManagerPage> {
backgroundColor: MyTheme.grayBg,
appBar: AppBar(
leading: Row(children: [
IconButton(icon: Icon(Icons.close), onPressed: clientClose),
IconButton(
icon: Icon(Icons.close),
onPressed: () => clientClose(gFFI.dialogManager)),
]),
centerTitle: true,
title: ToggleSwitch(
@@ -141,8 +144,8 @@ class _FileManagerPageState extends State<FileManagerPage> {
model.toggleSelectMode();
} else if (v == "folder") {
final name = TextEditingController();
DialogManager.show(
(setState, close) => CustomAlertDialog(
gFFI.dialogManager
.show((setState, close) => CustomAlertDialog(
title: Text(translate("Create Folder")),
content: Column(
mainAxisSize: MainAxisSize.min,

View File

@@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hbb/mobile/widgets/gesture_help.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:provider/provider.dart';
import 'package:wakelock/wakelock.dart';
@@ -51,7 +50,8 @@ class _RemotePageState extends State<RemotePage> {
gFFI.connect(widget.id);
WidgetsBinding.instance.addPostFrameCallback((_) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
showLoading(translate('Connecting...'));
gFFI.dialogManager
.showLoading(translate('Connecting...'), cancelToClose: true);
_interval =
Timer.periodic(Duration(milliseconds: 30), (timer) => interval());
});
@@ -71,7 +71,7 @@ class _RemotePageState extends State<RemotePage> {
gFFI.close();
_interval?.cancel();
_timer?.cancel();
SmartDialog.dismiss();
gFFI.dialogManager.dismissAll();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: SystemUiOverlay.values);
Wakelock.disable();
@@ -226,7 +226,7 @@ class _RemotePageState extends State<RemotePage> {
return WillPopScope(
onWillPop: () async {
clientClose();
clientClose(gFFI.dialogManager);
return false;
},
child: getRawPointerAndKeyBody(
@@ -401,7 +401,7 @@ class _RemotePageState extends State<RemotePage> {
color: Colors.white,
icon: Icon(Icons.clear),
onPressed: () {
clientClose();
clientClose(gFFI.dialogManager);
},
)
] +
@@ -411,7 +411,7 @@ class _RemotePageState extends State<RemotePage> {
icon: Icon(Icons.tv),
onPressed: () {
setState(() => _showEdit = false);
showOptions(widget.id);
showOptions(widget.id, gFFI.dialogManager);
},
)
] +
@@ -671,7 +671,7 @@ class _RemotePageState extends State<RemotePage> {
style: flatButtonStyle,
onPressed: () {
Navigator.pop(context);
showSetOSPassword(id, false);
showSetOSPassword(id, false, gFFI.dialogManager);
},
child: Icon(Icons.edit, color: MyTheme.accent),
)
@@ -739,12 +739,12 @@ class _RemotePageState extends State<RemotePage> {
if (password != null) {
bind.sessionInputOsPassword(id: widget.id, value: password);
} else {
showSetOSPassword(id, true);
showSetOSPassword(id, true, gFFI.dialogManager);
}
} else if (value == 'reset_canvas') {
gFFI.cursorModel.reset();
} else if (value == 'restart') {
showRestartRemoteDevice(pi, widget.id);
showRestartRemoteDevice(pi, widget.id, gFFI.dialogManager);
}
}();
}
@@ -1008,7 +1008,7 @@ class QualityMonitor extends StatelessWidget {
: SizedBox.shrink())));
}
void showOptions(String id) async {
void showOptions(String id, OverlayDialogManager dialogManager) async {
String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced';
if (quality == '') quality = 'balanced';
String viewStyle =
@@ -1026,7 +1026,7 @@ void showOptions(String id) async {
onTap: () {
if (i == cur) return;
bind.sessionSwitchDisplay(id: id, value: i);
SmartDialog.dismiss();
gFFI.dialogManager.dismissAll();
},
child: Ink(
width: 40,
@@ -1051,7 +1051,7 @@ void showOptions(String id) async {
}
final perms = gFFI.ffiModel.permissions;
DialogManager.show((setState, close) {
dialogManager.show((setState, close) {
final more = <Widget>[];
if (perms['audio'] != false) {
more.add(getToggle(id, setState, 'disable-audio', 'Mute'));
@@ -1107,9 +1107,10 @@ void showOptions(String id) async {
}, clickMaskDismiss: true, backDismiss: true);
}
void showRestartRemoteDevice(PeerInfo pi, String id) async {
void showRestartRemoteDevice(
PeerInfo pi, String id, OverlayDialogManager dialogManager) async {
final res =
await DialogManager.show<bool>((setState, close) => CustomAlertDialog(
await dialogManager.show<bool>((setState, close) => CustomAlertDialog(
title: Row(children: [
Icon(Icons.warning_amber_sharp,
color: Colors.redAccent, size: 28),
@@ -1128,12 +1129,13 @@ void showRestartRemoteDevice(PeerInfo pi, String id) async {
if (res == true) bind.sessionRestartRemoteDevice(id: id);
}
void showSetOSPassword(String id, bool login) async {
void showSetOSPassword(
String id, bool login, OverlayDialogManager dialogManager) async {
final controller = TextEditingController();
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) {
dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate('OS Password')),
content: Column(mainAxisSize: MainAxisSize.min, children: [

View File

@@ -63,7 +63,7 @@ class _ScanPageState extends State<ScanPage> {
var result = reader.decode(bitmap);
showServerSettingFromQr(result.text);
} catch (e) {
showToast('No QR code found');
gFFI.dialogManager.showToast('No QR code found');
}
}
}),
@@ -121,7 +121,7 @@ class _ScanPageState extends State<ScanPage> {
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
if (!p) {
showToast('No permisssion');
gFFI.dialogManager.showToast('No permisssion');
}
}
@@ -132,10 +132,10 @@ class _ScanPageState extends State<ScanPage> {
}
void showServerSettingFromQr(String data) async {
backToHome();
backToHomePage();
await controller?.pauseCamera();
if (!data.startsWith('config=')) {
showToast('Invalid QR code');
gFFI.dialogManager.showToast('Invalid QR code');
return;
}
try {
@@ -144,16 +144,16 @@ class _ScanPageState extends State<ScanPage> {
var key = values['key'] != null ? values['key'] as String : '';
var api = values['api'] != null ? values['api'] as String : '';
Timer(Duration(milliseconds: 60), () {
showServerSettingsWithValue(host, '', key, api);
showServerSettingsWithValue(host, '', key, api, gFFI.dialogManager);
});
} catch (e) {
showToast('Invalid QR code');
gFFI.dialogManager.showToast('Invalid QR code');
}
}
}
void showServerSettingsWithValue(
String id, String relay, String key, String api) async {
void showServerSettingsWithValue(String id, String relay, String key,
String api, OverlayDialogManager dialogManager) async {
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
String id0 = oldOptions['custom-rendezvous-server'] ?? "";
String relay0 = oldOptions['relay-server'] ?? "";
@@ -168,7 +168,7 @@ void showServerSettingsWithValue(
String? relayServerMsg;
String? apiServerMsg;
DialogManager.show((setState, close) {
dialogManager.show((setState, close) {
Future<bool> validate() async {
if (idController.text != id) {
final res = await validateAsync(idController.text);

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_hbb/mobile/widgets/dialog.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:provider/provider.dart';
import '../../common.dart';
@@ -90,9 +89,9 @@ class ServerPage extends StatefulWidget implements PageShape {
if (value == "changeID") {
// TODO
} else if (value == "setPermanentPassword") {
setPermanentPasswordDialog();
setPermanentPasswordDialog(gFFI.dialogManager);
} else if (value == "setTemporaryPasswordLength") {
setTemporaryPasswordLengthDialog();
setTemporaryPasswordLengthDialog(gFFI.dialogManager);
} else if (value == kUsePermanentPassword ||
value == kUseTemporaryPassword ||
value == kUseBothPasswords) {
@@ -522,7 +521,7 @@ void toAndroidChannelInit() {
switch (method) {
case "start_capture":
{
SmartDialog.dismiss();
gFFI.dialogManager.dismissAll();
gFFI.serverModel.updateClientState();
break;
}

View File

@@ -119,8 +119,8 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
if (v) {
PermissionManager.request("ignore_battery_optimizations");
} else {
final res = await DialogManager.show<bool>(
(setState, close) => CustomAlertDialog(
final res = await gFFI.dialogManager
.show<bool>((setState, close) => CustomAlertDialog(
title: Text(translate("Open System Setting")),
content: Text(translate(
"android_open_battery_optimizations_tip")),
@@ -153,9 +153,9 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
leading: Icon(Icons.person),
onPressed: (context) {
if (username == null) {
showLogin();
showLogin(gFFI.dialogManager);
} else {
logout();
logout(gFFI.dialogManager);
}
},
),
@@ -166,13 +166,13 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
title: Text(translate('ID/Relay Server')),
leading: Icon(Icons.cloud),
onPressed: (context) {
showServerSettings();
showServerSettings(gFFI.dialogManager);
}),
SettingsTile.navigation(
title: Text(translate('Language')),
leading: Icon(Icons.translate),
onPressed: (context) {
showLanguageSettings();
showLanguageSettings(gFFI.dialogManager);
})
]),
SettingsSection(
@@ -204,20 +204,20 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
}
}
void showServerSettings() async {
void showServerSettings(OverlayDialogManager dialogManager) 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);
showServerSettingsWithValue(id, relay, key, api, dialogManager);
}
void showLanguageSettings() async {
void showLanguageSettings(OverlayDialogManager dialogManager) async {
try {
final langs = json.decode(await bind.mainGetLangs()) as List<dynamic>;
var lang = await bind.mainGetLocalOption(key: "lang");
DialogManager.show((setState, close) {
dialogManager.show((setState, close) {
final setLang = (v) {
if (lang != v) {
setState(() {
@@ -246,8 +246,8 @@ void showLanguageSettings() async {
} catch (_e) {}
}
void showAbout() {
DialogManager.show((setState, close) {
void showAbout(OverlayDialogManager dialogManager) {
dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate('About') + ' RustDesk'),
content: Wrap(direction: Axis.vertical, spacing: 12, children: [
@@ -350,7 +350,7 @@ void refreshCurrentUser() async {
}
}
void logout() async {
void logout(OverlayDialogManager dialogManager) async {
final token = await bind.mainGetOption(key: "access_token");
if (token == '') return;
final url = getUrl();
@@ -363,7 +363,7 @@ void logout() async {
},
body: json.encode(body));
} catch (e) {
showToast('Failed to access $url');
dialogManager.showToast('Failed to access $url');
}
resetToken();
}
@@ -396,12 +396,12 @@ Future<String> getUrl() async {
return url;
}
void showLogin() {
void showLogin(OverlayDialogManager dialogManager) {
final passwordController = TextEditingController();
final nameController = TextEditingController();
var loading = false;
var error = '';
DialogManager.show((setState, close) {
dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate('Login')),
content: Column(mainAxisSize: MainAxisSize.min, children: [

View File

@@ -1,32 +1,31 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import '../../common.dart';
import '../../models/platform_model.dart';
void clientClose() {
msgBox('', 'Close', 'Are you sure to close the connection?');
void clientClose(OverlayDialogManager dialogManager) {
msgBox('', 'Close', 'Are you sure to close the connection?', dialogManager);
}
const SEC1 = Duration(seconds: 1);
void showSuccess({Duration duration = SEC1}) {
SmartDialog.dismiss();
showToast(translate("Successful"), duration: SEC1);
// TODO
// showToast(translate("Successful"), duration: SEC1);
}
void showError({Duration duration = SEC1}) {
SmartDialog.dismiss();
showToast(translate("Error"), duration: SEC1);
// TODO
// showToast(translate("Error"), duration: SEC1);
}
void setPermanentPasswordDialog() async {
void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
final pw = await bind.mainGetPermanentPassword();
final p0 = TextEditingController(text: pw);
final p1 = TextEditingController(text: pw);
var validateLength = false;
var validateSame = false;
DialogManager.show((setState, close) {
dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate('Set your own password')),
content: Form(
@@ -86,7 +85,7 @@ void setPermanentPasswordDialog() async {
onPressed: (validateLength && validateSame)
? () async {
close();
showLoading(translate("Waiting"));
dialogManager.showLoading(translate("Waiting"));
if (await gFFI.serverModel.setPermanentPassword(p0.text)) {
showSuccess();
} else {
@@ -101,13 +100,14 @@ void setPermanentPasswordDialog() async {
});
}
void setTemporaryPasswordLengthDialog() async {
void setTemporaryPasswordLengthDialog(
OverlayDialogManager dialogManager) async {
List<String> lengths = ['6', '8', '10'];
String length = await bind.mainGetOption(key: "temporary-password-length");
var index = lengths.indexOf(length);
if (index < 0) index = 0;
length = lengths[index];
DialogManager.show((setState, close) {
dialogManager.show((setState, close) {
final setLength = (newValue) {
final oldValue = length;
if (oldValue == newValue) return;
@@ -133,10 +133,11 @@ void setTemporaryPasswordLengthDialog() async {
}, backDismiss: true, clickMaskDismiss: true);
}
void enterPasswordDialog(String id) async {
void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async {
final controller = TextEditingController();
var remember = await bind.getSessionRemember(id: id) ?? false;
DialogManager.show((setState, close) {
dialogManager.dismissAll();
dialogManager.show((setState, close) {
return CustomAlertDialog(
title: Text(translate('Password Required')),
content: Column(mainAxisSize: MainAxisSize.min, children: [
@@ -161,7 +162,7 @@ void enterPasswordDialog(String id) async {
style: flatButtonStyle,
onPressed: () {
close();
backToHome();
backToHomePage();
},
child: Text(translate('Cancel')),
),
@@ -172,7 +173,8 @@ void enterPasswordDialog(String id) async {
if (text == '') return;
gFFI.login(id, text, remember);
close();
showLoading(translate('Logging in...'));
dialogManager.showLoading(translate('Logging in...'),
cancelToClose: true);
},
child: Text(translate('OK')),
),
@@ -181,8 +183,8 @@ void enterPasswordDialog(String id) async {
});
}
void wrongPasswordDialog(String id) {
DialogManager.show((setState, close) => CustomAlertDialog(
void wrongPasswordDialog(String id, OverlayDialogManager dialogManager) {
dialogManager.show((setState, close) => CustomAlertDialog(
title: Text(translate('Wrong Password')),
content: Text(translate('Do you want to enter again?')),
actions: [
@@ -190,14 +192,14 @@ void wrongPasswordDialog(String id) {
style: flatButtonStyle,
onPressed: () {
close();
backToHome();
backToHomePage();
},
child: Text(translate('Cancel')),
),
TextButton(
style: flatButtonStyle,
onPressed: () {
enterPasswordDialog(id);
enterPasswordDialog(id, dialogManager);
},
child: Text(translate('Retry')),
),
@@ -239,8 +241,8 @@ class _PasswordWidgetState extends State<PasswordWidget> {
//This will obscure text dynamically
keyboardType: TextInputType.visiblePassword,
decoration: InputDecoration(
labelText: Translator.call('Password'),
hintText: Translator.call('Enter your password'),
labelText: translate('Password'),
hintText: translate('Enter your password'),
// Here is key idea
suffixIcon: IconButton(
icon: Icon(