new dialog impl based on Overlay
This commit is contained in:
parent
2e9a6ed4f6
commit
e6329dc7eb
@ -4,10 +4,10 @@ import 'dart:io';
|
|||||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:get/instance_manager.dart';
|
import 'package:get/instance_manager.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:window_manager/window_manager.dart';
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
import 'package:back_button_interceptor/back_button_interceptor.dart';
|
||||||
|
|
||||||
import 'models/model.dart';
|
import 'models/model.dart';
|
||||||
import 'models/platform_model.dart';
|
import 'models/platform_model.dart';
|
||||||
@ -26,10 +26,6 @@ int androidVersion = 0;
|
|||||||
typedef F = String Function(String);
|
typedef F = String Function(String);
|
||||||
typedef FMethod = String Function(String, dynamic);
|
typedef FMethod = String Function(String, dynamic);
|
||||||
|
|
||||||
class Translator {
|
|
||||||
static late F call;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyTheme {
|
class MyTheme {
|
||||||
MyTheme._();
|
MyTheme._();
|
||||||
|
|
||||||
@ -71,44 +67,12 @@ final ButtonStyle flatButtonStyle = TextButton.styleFrom(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
void showToast(String text, {Duration? duration}) {
|
backToHomePage() {
|
||||||
SmartDialog.showToast(text, displayTime: duration);
|
if (isAndroid || isIOS) {
|
||||||
}
|
Navigator.popUntil(globalKey.currentContext!, ModalRoute.withName("/"));
|
||||||
|
} else {
|
||||||
void showLoading(String text, {bool clickMaskDismiss = false}) {
|
// TODO desktop
|
||||||
SmartDialog.dismiss();
|
}
|
||||||
SmartDialog.showLoading(
|
|
||||||
clickMaskDismiss: false,
|
|
||||||
builder: (context) {
|
|
||||||
return Container(
|
|
||||||
color: MyTheme.white,
|
|
||||||
constraints: BoxConstraints(maxWidth: 240),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(height: 30),
|
|
||||||
Center(child: CircularProgressIndicator()),
|
|
||||||
SizedBox(height: 20),
|
|
||||||
Center(
|
|
||||||
child: Text(Translator.call(text),
|
|
||||||
style: TextStyle(fontSize: 15))),
|
|
||||||
SizedBox(height: 20),
|
|
||||||
Center(
|
|
||||||
child: TextButton(
|
|
||||||
style: flatButtonStyle,
|
|
||||||
onPressed: () {
|
|
||||||
SmartDialog.dismiss();
|
|
||||||
backToHome();
|
|
||||||
},
|
|
||||||
child: Text(Translator.call('Cancel'),
|
|
||||||
style: TextStyle(color: MyTheme.accent))))
|
|
||||||
]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
backToHome() {
|
|
||||||
Navigator.popUntil(globalKey.currentContext!, ModalRoute.withName("/"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_on_top(int? id) {
|
void window_on_top(int? id) {
|
||||||
@ -127,51 +91,140 @@ void window_on_top(int? id) {
|
|||||||
typedef DialogBuilder = CustomAlertDialog Function(
|
typedef DialogBuilder = CustomAlertDialog Function(
|
||||||
StateSetter setState, void Function([dynamic]) close);
|
StateSetter setState, void Function([dynamic]) close);
|
||||||
|
|
||||||
class DialogManager {
|
class Dialog<T> {
|
||||||
static int _tag = 0;
|
OverlayEntry? entry;
|
||||||
|
Completer<T?> completer = Completer<T>();
|
||||||
|
|
||||||
static dismissByTag(String tag, [result]) {
|
Dialog();
|
||||||
SmartDialog.dismiss(tag: tag, result: result);
|
|
||||||
|
void complete(T? res) {
|
||||||
|
try {
|
||||||
|
if (!completer.isCompleted) {
|
||||||
|
completer.complete(res);
|
||||||
|
}
|
||||||
|
entry?.remove();
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Dialog complete catch error: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OverlayDialogManager {
|
||||||
|
OverlayState? _overlayState;
|
||||||
|
Map<String, Dialog> _dialogs = Map();
|
||||||
|
int _tagCount = 0;
|
||||||
|
|
||||||
|
/// By default OverlayDialogManager use global overlay
|
||||||
|
OverlayDialogManager() {
|
||||||
|
_overlayState = globalKey.currentState?.overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<T?> show<T>(DialogBuilder builder,
|
void setOverlayState(OverlayState? overlayState) {
|
||||||
|
_overlayState = overlayState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dismissAll() {
|
||||||
|
_dialogs.forEach((key, value) {
|
||||||
|
value.complete(null);
|
||||||
|
BackButtonInterceptor.removeByName(key);
|
||||||
|
});
|
||||||
|
_dialogs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dismissByTag(String tag) {
|
||||||
|
_dialogs[tag]?.complete(null);
|
||||||
|
_dialogs.remove(tag);
|
||||||
|
BackButtonInterceptor.removeByName(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO clickMaskDismiss
|
||||||
|
Future<T?> show<T>(DialogBuilder builder,
|
||||||
{bool clickMaskDismiss = false,
|
{bool clickMaskDismiss = false,
|
||||||
bool backDismiss = false,
|
bool backDismiss = false,
|
||||||
String? tag,
|
String? tag,
|
||||||
bool useAnimation = true}) async {
|
bool useAnimation = true,
|
||||||
final t;
|
bool forceGlobal = false}) {
|
||||||
if (tag != null) {
|
final overlayState =
|
||||||
t = tag;
|
forceGlobal ? globalKey.currentState?.overlay : _overlayState;
|
||||||
} else {
|
|
||||||
_tag += 1;
|
if (overlayState == null) {
|
||||||
t = _tag.toString();
|
return Future.error(
|
||||||
|
"[OverlayDialogManager] Failed to show dialog, _overlayState is null, call [setOverlayState] first");
|
||||||
}
|
}
|
||||||
SmartDialog.dismiss(status: SmartStatus.allToast);
|
|
||||||
SmartDialog.dismiss(status: SmartStatus.loading);
|
final _tag;
|
||||||
|
if (tag != null) {
|
||||||
|
_tag = tag;
|
||||||
|
} else {
|
||||||
|
_tag = _tagCount.toString();
|
||||||
|
_tagCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
final dialog = Dialog<T>();
|
||||||
|
_dialogs[_tag] = dialog;
|
||||||
|
|
||||||
final close = ([res]) {
|
final close = ([res]) {
|
||||||
SmartDialog.dismiss(tag: t, result: res);
|
_dialogs.remove(_tag);
|
||||||
|
dialog.complete(res);
|
||||||
|
BackButtonInterceptor.removeByName(_tag);
|
||||||
};
|
};
|
||||||
final res = await SmartDialog.show<T>(
|
dialog.entry = OverlayEntry(builder: (_) {
|
||||||
tag: t,
|
return Container(
|
||||||
clickMaskDismiss: clickMaskDismiss,
|
color: Colors.transparent,
|
||||||
backDismiss: backDismiss,
|
child: StatefulBuilder(
|
||||||
useAnimation: useAnimation,
|
builder: (_, setState) => builder(setState, close)));
|
||||||
builder: (_) => StatefulBuilder(
|
});
|
||||||
builder: (_, setState) => builder(setState, close)));
|
overlayState.insert(dialog.entry!);
|
||||||
return res;
|
BackButtonInterceptor.add((stopDefaultButtonEvent, routeInfo) {
|
||||||
|
if (backDismiss) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}, name: _tag);
|
||||||
|
return dialog.completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showLoading(String text,
|
||||||
|
{bool clickMaskDismiss = false, bool cancelToClose = false}) {
|
||||||
|
show((setState, close) => CustomAlertDialog(
|
||||||
|
content: Container(
|
||||||
|
color: MyTheme.white,
|
||||||
|
constraints: BoxConstraints(maxWidth: 240),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 30),
|
||||||
|
Center(child: CircularProgressIndicator()),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Center(
|
||||||
|
child: Text(translate(text),
|
||||||
|
style: TextStyle(fontSize: 15))),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
Center(
|
||||||
|
child: TextButton(
|
||||||
|
style: flatButtonStyle,
|
||||||
|
onPressed: () {
|
||||||
|
dismissAll();
|
||||||
|
if (cancelToClose) backToHomePage();
|
||||||
|
},
|
||||||
|
child: Text(translate('Cancel'),
|
||||||
|
style: TextStyle(color: MyTheme.accent))))
|
||||||
|
]))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void showToast(String text) {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomAlertDialog extends StatelessWidget {
|
class CustomAlertDialog extends StatelessWidget {
|
||||||
CustomAlertDialog(
|
CustomAlertDialog(
|
||||||
{required this.title,
|
{this.title, required this.content, this.actions, this.contentPadding});
|
||||||
required this.content,
|
|
||||||
required this.actions,
|
|
||||||
this.contentPadding});
|
|
||||||
|
|
||||||
final Widget title;
|
final Widget? title;
|
||||||
final Widget content;
|
final Widget content;
|
||||||
final List<Widget> actions;
|
final List<Widget>? actions;
|
||||||
final double? contentPadding;
|
final double? contentPadding;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -187,7 +240,9 @@ class CustomAlertDialog extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void msgBox(String type, String title, String text, {bool? hasCancel}) {
|
void msgBox(
|
||||||
|
String type, String title, String text, OverlayDialogManager dialogManager,
|
||||||
|
{bool? hasCancel}) {
|
||||||
var wrap = (String text, void Function() onPressed) => ButtonTheme(
|
var wrap = (String text, void Function() onPressed) => ButtonTheme(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
@ -198,17 +253,17 @@ void msgBox(String type, String title, String text, {bool? hasCancel}) {
|
|||||||
child: TextButton(
|
child: TextButton(
|
||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: Text(Translator.call(text),
|
child:
|
||||||
style: TextStyle(color: MyTheme.accent))));
|
Text(translate(text), style: TextStyle(color: MyTheme.accent))));
|
||||||
|
|
||||||
SmartDialog.dismiss();
|
dialogManager.dismissAll();
|
||||||
List<Widget> buttons = [];
|
List<Widget> buttons = [];
|
||||||
if (type != "connecting" && type != "success" && type.indexOf("nook") < 0) {
|
if (type != "connecting" && type != "success" && type.indexOf("nook") < 0) {
|
||||||
buttons.insert(
|
buttons.insert(
|
||||||
0,
|
0,
|
||||||
wrap(Translator.call('OK'), () {
|
wrap(translate('OK'), () {
|
||||||
SmartDialog.dismiss();
|
dialogManager.dismissAll();
|
||||||
backToHome();
|
backToHomePage();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (hasCancel == null) {
|
if (hasCancel == null) {
|
||||||
@ -220,21 +275,21 @@ void msgBox(String type, String title, String text, {bool? hasCancel}) {
|
|||||||
if (hasCancel) {
|
if (hasCancel) {
|
||||||
buttons.insert(
|
buttons.insert(
|
||||||
0,
|
0,
|
||||||
wrap(Translator.call('Cancel'), () {
|
wrap(translate('Cancel'), () {
|
||||||
SmartDialog.dismiss();
|
dialogManager.dismissAll();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// TODO: test this button
|
// TODO: test this button
|
||||||
if (type.indexOf("hasclose") >= 0) {
|
if (type.indexOf("hasclose") >= 0) {
|
||||||
buttons.insert(
|
buttons.insert(
|
||||||
0,
|
0,
|
||||||
wrap(Translator.call('Close'), () {
|
wrap(translate('Close'), () {
|
||||||
SmartDialog.dismiss();
|
dialogManager.dismissAll();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
DialogManager.show((setState, close) => CustomAlertDialog(
|
dialogManager.show((setState, close) => CustomAlertDialog(
|
||||||
title: Text(translate(title), style: TextStyle(fontSize: 21)),
|
title: Text(translate(title), style: TextStyle(fontSize: 21)),
|
||||||
content: Text(Translator.call(text), style: TextStyle(fontSize: 15)),
|
content: Text(translate(text), style: TextStyle(fontSize: 15)),
|
||||||
actions: buttons));
|
actions: buttons));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
var field = "";
|
var field = "";
|
||||||
var msg = "";
|
var msg = "";
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Add ID")),
|
title: Text(translate("Add ID")),
|
||||||
content: Column(
|
content: Column(
|
||||||
@ -698,7 +698,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
var field = "";
|
var field = "";
|
||||||
var msg = "";
|
var msg = "";
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Add Tag")),
|
title: Text(translate("Add Tag")),
|
||||||
content: Column(
|
content: Column(
|
||||||
@ -769,7 +769,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
final tags = List.of(gFFI.abModel.tags);
|
final tags = List.of(gFFI.abModel.tags);
|
||||||
var selectedTag = gFFI.abModel.getPeerTags(id).obs;
|
var selectedTag = gFFI.abModel.getPeerTags(id).obs;
|
||||||
|
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Edit Tag")),
|
title: Text(translate("Edit Tag")),
|
||||||
content: Column(
|
content: Column(
|
||||||
@ -884,16 +884,16 @@ class _WebMenuState extends State<WebMenu> {
|
|||||||
},
|
},
|
||||||
onSelected: (value) {
|
onSelected: (value) {
|
||||||
if (value == 'server') {
|
if (value == 'server') {
|
||||||
showServerSettings();
|
showServerSettings(gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
if (value == 'about') {
|
if (value == 'about') {
|
||||||
showAbout();
|
showAbout(gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
if (value == 'login') {
|
if (value == 'login') {
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
showLogin();
|
showLogin(gFFI.dialogManager);
|
||||||
} else {
|
} else {
|
||||||
logout();
|
logout(gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value == 'scan') {
|
if (value == 'scan') {
|
||||||
|
@ -116,7 +116,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
onDoubleTap: () {
|
onDoubleTap: () {
|
||||||
Clipboard.setData(
|
Clipboard.setData(
|
||||||
ClipboardData(text: model.serverId.text));
|
ClipboardData(text: model.serverId.text));
|
||||||
showToast(translate("Copied"));
|
gFFI.dialogManager.showToast(translate("Copied"));
|
||||||
},
|
},
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: model.serverId,
|
controller: model.serverId,
|
||||||
@ -253,7 +253,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
kUsePermanentPassword) {
|
kUsePermanentPassword) {
|
||||||
Clipboard.setData(
|
Clipboard.setData(
|
||||||
ClipboardData(text: model.serverPasswd.text));
|
ClipboardData(text: model.serverPasswd.text));
|
||||||
showToast(translate("Copied"));
|
gFFI.dialogManager.showToast(translate("Copied"));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
@ -604,7 +604,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
var newId = "";
|
var newId = "";
|
||||||
var msg = "";
|
var msg = "";
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Change ID")),
|
title: Text(translate("Change ID")),
|
||||||
content: Column(
|
content: Column(
|
||||||
@ -690,7 +690,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
var key = oldOptions['key'] ?? "";
|
var key = oldOptions['key'] ?? "";
|
||||||
|
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("ID/Relay Server")),
|
title: Text(translate("ID/Relay Server")),
|
||||||
content: ConstrainedBox(
|
content: ConstrainedBox(
|
||||||
@ -891,7 +891,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
var newWhiteListField = newWhiteList.join('\n');
|
var newWhiteListField = newWhiteList.join('\n');
|
||||||
var msg = "";
|
var msg = "";
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("IP Whitelisting")),
|
title: Text(translate("IP Whitelisting")),
|
||||||
content: Column(
|
content: Column(
|
||||||
@ -980,7 +980,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Socks5 Proxy")),
|
title: Text(translate("Socks5 Proxy")),
|
||||||
content: ConstrainedBox(
|
content: ConstrainedBox(
|
||||||
@ -1117,7 +1117,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
final license = await bind.mainGetLicense();
|
final license = await bind.mainGetLicense();
|
||||||
final version = await bind.mainGetVersion();
|
final version = await bind.mainGetVersion();
|
||||||
final linkStyle = TextStyle(decoration: TextDecoration.underline);
|
final linkStyle = TextStyle(decoration: TextDecoration.underline);
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text("About $appName"),
|
title: Text("About $appName"),
|
||||||
content: ConstrainedBox(
|
content: ConstrainedBox(
|
||||||
@ -1208,7 +1208,7 @@ Future<bool> loginDialog() async {
|
|||||||
|
|
||||||
var isInProgress = false;
|
var isInProgress = false;
|
||||||
var completer = Completer<bool>();
|
var completer = Completer<bool>();
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Login")),
|
title: Text(translate("Login")),
|
||||||
content: ConstrainedBox(
|
content: ConstrainedBox(
|
||||||
@ -1339,7 +1339,7 @@ void setPasswordDialog() async {
|
|||||||
var errMsg0 = "";
|
var errMsg0 = "";
|
||||||
var errMsg1 = "";
|
var errMsg1 = "";
|
||||||
|
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Set Password")),
|
title: Text(translate("Set Password")),
|
||||||
content: ConstrainedBox(
|
content: ConstrainedBox(
|
||||||
|
@ -4,7 +4,6 @@ import 'dart:math';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/mobile/pages/file_manager_page.dart';
|
import 'package:flutter_hbb/mobile/pages/file_manager_page.dart';
|
||||||
import 'package:flutter_hbb/models/file_model.dart';
|
import 'package:flutter_hbb/models/file_model.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
@ -26,8 +25,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
final _localSelectedItems = SelectedItems();
|
final _localSelectedItems = SelectedItems();
|
||||||
final _remoteSelectedItems = SelectedItems();
|
final _remoteSelectedItems = SelectedItems();
|
||||||
|
|
||||||
/// FFI with name file_transfer_id
|
late FFI _ffi;
|
||||||
FFI get _ffi => ffi('ft_${widget.id}');
|
|
||||||
|
|
||||||
FileModel get model => _ffi.fileModel;
|
FileModel get model => _ffi.fileModel;
|
||||||
|
|
||||||
@ -38,8 +36,9 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
Get.put(FFI()..connect(widget.id, isFileTransfer: true),
|
_ffi = FFI();
|
||||||
tag: 'ft_${widget.id}');
|
_ffi.connect(widget.id, isFileTransfer: true);
|
||||||
|
Get.put(_ffi, tag: 'ft_${widget.id}');
|
||||||
// _ffi.ffiModel.updateEventListener(widget.id);
|
// _ffi.ffiModel.updateEventListener(widget.id);
|
||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
@ -51,7 +50,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
model.onClose();
|
model.onClose();
|
||||||
_ffi.close();
|
_ffi.close();
|
||||||
SmartDialog.dismiss();
|
_ffi.dialogManager.dismissAll();
|
||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
Wakelock.disable();
|
Wakelock.disable();
|
||||||
}
|
}
|
||||||
@ -552,7 +551,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final name = TextEditingController();
|
final name = TextEditingController();
|
||||||
DialogManager.show((setState, close) =>
|
_ffi.dialogManager.show((setState, close) =>
|
||||||
CustomAlertDialog(
|
CustomAlertDialog(
|
||||||
title: Text(translate("Create Folder")),
|
title: Text(translate("Create Folder")),
|
||||||
content: Column(
|
content: Column(
|
||||||
|
@ -7,9 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hbb/mobile/widgets/gesture_help.dart';
|
import 'package:flutter_hbb/mobile/widgets/gesture_help.dart';
|
||||||
import 'package:flutter_hbb/models/chat_model.dart';
|
import 'package:flutter_hbb/models/chat_model.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/route_manager.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
|
||||||
@ -51,18 +49,19 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
var _showEdit = false; // use soft keyboard
|
var _showEdit = false; // use soft keyboard
|
||||||
var _isPhysicalMouse = false;
|
var _isPhysicalMouse = false;
|
||||||
|
|
||||||
FFI get _ffi => ffi(widget.id);
|
late FFI _ffi;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
var ffitmp = FFI();
|
_ffi = FFI();
|
||||||
ffitmp.canvasModel.tabBarHeight = super.widget.tabBarHeight;
|
_ffi.canvasModel.tabBarHeight = super.widget.tabBarHeight;
|
||||||
final ffi = Get.put(ffitmp, tag: widget.id);
|
Get.put(_ffi, tag: widget.id);
|
||||||
ffi.connect(widget.id, tabBarHeight: super.widget.tabBarHeight);
|
_ffi.connect(widget.id, tabBarHeight: super.widget.tabBarHeight);
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
||||||
showLoading(translate('Connecting...'));
|
_ffi.dialogManager
|
||||||
|
.showLoading(translate('Connecting...'), cancelToClose: true);
|
||||||
_interval =
|
_interval =
|
||||||
Timer.periodic(Duration(milliseconds: 30), (timer) => interval());
|
Timer.periodic(Duration(milliseconds: 30), (timer) => interval());
|
||||||
});
|
});
|
||||||
@ -70,8 +69,8 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
}
|
}
|
||||||
_physicalFocusNode.requestFocus();
|
_physicalFocusNode.requestFocus();
|
||||||
ffi.ffiModel.updateEventListener(widget.id);
|
_ffi.ffiModel.updateEventListener(widget.id);
|
||||||
ffi.listenToMouse(true);
|
_ffi.listenToMouse(true);
|
||||||
// WindowManager.instance.addListener(this);
|
// WindowManager.instance.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +85,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
_ffi.close();
|
_ffi.close();
|
||||||
_interval?.cancel();
|
_interval?.cancel();
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
SmartDialog.dismiss();
|
_ffi.dialogManager.dismissAll();
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
overlays: SystemUiOverlay.values);
|
overlays: SystemUiOverlay.values);
|
||||||
if (!Platform.isLinux) {
|
if (!Platform.isLinux) {
|
||||||
@ -262,8 +261,11 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
initialEntries: [
|
initialEntries: [
|
||||||
OverlayEntry(builder: (context) {
|
OverlayEntry(builder: (context) {
|
||||||
_ffi.chatModel.setOverlayState(Overlay.of(context));
|
_ffi.chatModel.setOverlayState(Overlay.of(context));
|
||||||
|
_ffi.dialogManager.setOverlayState(Overlay.of(context));
|
||||||
return Container(
|
return Container(
|
||||||
child: getRawPointerAndKeyBody(getBodyForDesktop(keyboard)));
|
color: Colors.black,
|
||||||
|
child: getRawPointerAndKeyBody(
|
||||||
|
getBodyForDesktop(context, keyboard)));
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
@ -275,7 +277,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
_ffi.canvasModel.tabBarHeight = super.widget.tabBarHeight;
|
_ffi.canvasModel.tabBarHeight = super.widget.tabBarHeight;
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
clientClose();
|
clientClose(_ffi.dialogManager);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: MultiProvider(
|
child: MultiProvider(
|
||||||
@ -410,7 +412,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
icon: Icon(Icons.clear),
|
icon: Icon(Icons.clear),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
clientClose();
|
clientClose(_ffi.dialogManager);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
] +
|
] +
|
||||||
@ -420,7 +422,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
icon: Icon(Icons.tv),
|
icon: Icon(Icons.tv),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() => _showEdit = false);
|
setState(() => _showEdit = false);
|
||||||
showOptions(widget.id);
|
showOptions(widget.id, _ffi.dialogManager);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
] +
|
] +
|
||||||
@ -497,7 +499,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
/// DoubleFiner -> right click
|
/// DoubleFiner -> right click
|
||||||
/// HoldDrag -> left drag
|
/// HoldDrag -> left drag
|
||||||
|
|
||||||
Widget getBodyForDesktop(bool keyboard) {
|
Widget getBodyForDesktop(BuildContext context, bool keyboard) {
|
||||||
var paints = <Widget>[
|
var paints = <Widget>[
|
||||||
MouseRegion(onEnter: (evt) {
|
MouseRegion(onEnter: (evt) {
|
||||||
bind.hostStopSystemKeyPropagate(stopped: false);
|
bind.hostStopSystemKeyPropagate(stopped: false);
|
||||||
@ -567,7 +569,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
showSetOSPassword(widget.id, false);
|
showSetOSPassword(widget.id, false, _ffi.dialogManager);
|
||||||
},
|
},
|
||||||
child: Icon(Icons.edit, color: MyTheme.accent),
|
child: Icon(Icons.edit, color: MyTheme.accent),
|
||||||
)
|
)
|
||||||
@ -632,7 +634,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
if (password != null) {
|
if (password != null) {
|
||||||
bind.sessionInputOsPassword(id: widget.id, value: password);
|
bind.sessionInputOsPassword(id: widget.id, value: password);
|
||||||
} else {
|
} else {
|
||||||
showSetOSPassword(widget.id, true);
|
showSetOSPassword(widget.id, true, _ffi.dialogManager);
|
||||||
}
|
}
|
||||||
} else if (value == 'reset_canvas') {
|
} else if (value == 'reset_canvas') {
|
||||||
_ffi.cursorModel.reset();
|
_ffi.cursorModel.reset();
|
||||||
@ -889,7 +891,7 @@ class ImagePainter extends CustomPainter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showOptions(String id) async {
|
void showOptions(String id, OverlayDialogManager dialogManager) async {
|
||||||
String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced';
|
String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced';
|
||||||
if (quality == '') quality = 'balanced';
|
if (quality == '') quality = 'balanced';
|
||||||
String viewStyle =
|
String viewStyle =
|
||||||
@ -907,7 +909,7 @@ void showOptions(String id) async {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
if (i == cur) return;
|
if (i == cur) return;
|
||||||
bind.sessionSwitchDisplay(id: id, value: i);
|
bind.sessionSwitchDisplay(id: id, value: i);
|
||||||
SmartDialog.dismiss();
|
dialogManager.dismissAll();
|
||||||
},
|
},
|
||||||
child: Ink(
|
child: Ink(
|
||||||
width: 40,
|
width: 40,
|
||||||
@ -932,7 +934,7 @@ void showOptions(String id) async {
|
|||||||
}
|
}
|
||||||
final perms = ffi(id).ffiModel.permissions;
|
final perms = ffi(id).ffiModel.permissions;
|
||||||
|
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
final more = <Widget>[];
|
final more = <Widget>[];
|
||||||
if (perms['audio'] != false) {
|
if (perms['audio'] != false) {
|
||||||
more.add(getToggle(id, setState, 'disable-audio', 'Mute'));
|
more.add(getToggle(id, setState, 'disable-audio', 'Mute'));
|
||||||
@ -990,12 +992,13 @@ void showOptions(String id) async {
|
|||||||
}, clickMaskDismiss: true, backDismiss: true);
|
}, clickMaskDismiss: true, backDismiss: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showSetOSPassword(String id, bool login) async {
|
void showSetOSPassword(
|
||||||
|
String id, bool login, OverlayDialogManager dialogManager) async {
|
||||||
final controller = TextEditingController();
|
final controller = TextEditingController();
|
||||||
var password = await bind.getSessionOption(id: id, arg: "os-password") ?? "";
|
var password = await bind.getSessionOption(id: id, arg: "os-password") ?? "";
|
||||||
var autoLogin = await bind.getSessionOption(id: id, arg: "auto-login") != "";
|
var autoLogin = await bind.getSessionOption(id: id, arg: "auto-login") != "";
|
||||||
controller.text = password;
|
controller.text = password;
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('OS Password')),
|
title: Text(translate('OS Password')),
|
||||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/common.dart';
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/file_manager_tab_page.dart';
|
import 'package:flutter_hbb/desktop/pages/file_manager_tab_page.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
/// multi-tab file transfer remote screen
|
/// multi-tab file transfer remote screen
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/common.dart';
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/connection_tab_page.dart';
|
import 'package:flutter_hbb/desktop/pages/connection_tab_page.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
/// multi-tab desktop remote screen
|
/// multi-tab desktop remote screen
|
||||||
|
@ -258,7 +258,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
final tags = List.of(gFFI.abModel.tags);
|
final tags = List.of(gFFI.abModel.tags);
|
||||||
var selectedTag = gFFI.abModel.getPeerTags(id).obs;
|
var selectedTag = gFFI.abModel.getPeerTags(id).obs;
|
||||||
|
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Edit Tag")),
|
title: Text(translate("Edit Tag")),
|
||||||
content: Column(
|
content: Column(
|
||||||
@ -314,7 +314,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final k = GlobalKey<FormState>();
|
final k = GlobalKey<FormState>();
|
||||||
DialogManager.show((setState, close) {
|
gFFI.dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Rename")),
|
title: Text(translate("Rename")),
|
||||||
content: Column(
|
content: Column(
|
||||||
|
@ -5,7 +5,6 @@ import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
|||||||
import 'package:flutter_hbb/desktop/screen/desktop_file_transfer_screen.dart';
|
import 'package:flutter_hbb/desktop/screen/desktop_file_transfer_screen.dart';
|
||||||
import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart';
|
import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart';
|
||||||
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get/route_manager.dart';
|
import 'package:get/route_manager.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -95,14 +94,7 @@ void runRemoteScreen(Map<String, dynamic> argument) async {
|
|||||||
),
|
),
|
||||||
navigatorObservers: [
|
navigatorObservers: [
|
||||||
// FirebaseAnalyticsObserver(analytics: analytics),
|
// FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
FlutterSmartDialog.observer
|
|
||||||
],
|
],
|
||||||
builder: FlutterSmartDialog.init(
|
|
||||||
builder: isAndroid
|
|
||||||
? (_, child) => AccessibilityListener(
|
|
||||||
child: child,
|
|
||||||
)
|
|
||||||
: null),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,14 +108,7 @@ void runFileTransferScreen(Map<String, dynamic> argument) async {
|
|||||||
home: DesktopFileTransferScreen(params: argument),
|
home: DesktopFileTransferScreen(params: argument),
|
||||||
navigatorObservers: [
|
navigatorObservers: [
|
||||||
// FirebaseAnalyticsObserver(analytics: analytics),
|
// FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
FlutterSmartDialog.observer
|
]));
|
||||||
],
|
|
||||||
builder: FlutterSmartDialog.init(
|
|
||||||
builder: isAndroid
|
|
||||||
? (_, child) => AccessibilityListener(
|
|
||||||
child: child,
|
|
||||||
)
|
|
||||||
: null)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatelessWidget {
|
||||||
@ -153,14 +138,12 @@ class App extends StatelessWidget {
|
|||||||
: HomePage(),
|
: HomePage(),
|
||||||
navigatorObservers: [
|
navigatorObservers: [
|
||||||
// FirebaseAnalyticsObserver(analytics: analytics),
|
// FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
FlutterSmartDialog.observer
|
|
||||||
],
|
],
|
||||||
builder: FlutterSmartDialog.init(
|
builder: isAndroid
|
||||||
builder: isAndroid
|
? (_, child) => AccessibilityListener(
|
||||||
? (_, child) => AccessibilityListener(
|
child: child,
|
||||||
child: child,
|
)
|
||||||
)
|
: null),
|
||||||
: null)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,16 +380,16 @@ class _WebMenuState extends State<WebMenu> {
|
|||||||
},
|
},
|
||||||
onSelected: (value) {
|
onSelected: (value) {
|
||||||
if (value == 'server') {
|
if (value == 'server') {
|
||||||
showServerSettings();
|
showServerSettings(gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
if (value == 'about') {
|
if (value == 'about') {
|
||||||
showAbout();
|
showAbout(gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
if (value == 'login') {
|
if (value == 'login') {
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
showLogin();
|
showLogin(gFFI.dialogManager);
|
||||||
} else {
|
} else {
|
||||||
logout();
|
logout(gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value == 'scan') {
|
if (value == 'scan') {
|
||||||
|
@ -3,13 +3,11 @@ import 'dart:async';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
|
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
|
||||||
import 'package:flutter_hbb/models/file_model.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:provider/provider.dart';
|
||||||
import 'package:toggle_switch/toggle_switch.dart';
|
import 'package:toggle_switch/toggle_switch.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
import '../../models/model.dart';
|
|
||||||
import '../widgets/dialog.dart';
|
import '../widgets/dialog.dart';
|
||||||
|
|
||||||
class FileManagerPage extends StatefulWidget {
|
class FileManagerPage extends StatefulWidget {
|
||||||
@ -29,7 +27,10 @@ class _FileManagerPageState extends State<FileManagerPage> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
gFFI.connect(widget.id, isFileTransfer: true);
|
gFFI.connect(widget.id, isFileTransfer: true);
|
||||||
showLoading(translate('Connecting...'));
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
gFFI.dialogManager
|
||||||
|
.showLoading(translate('Connecting...'), cancelToClose: true);
|
||||||
|
});
|
||||||
gFFI.ffiModel.updateEventListener(widget.id);
|
gFFI.ffiModel.updateEventListener(widget.id);
|
||||||
Wakelock.enable();
|
Wakelock.enable();
|
||||||
}
|
}
|
||||||
@ -38,7 +39,7 @@ class _FileManagerPageState extends State<FileManagerPage> {
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
model.onClose();
|
model.onClose();
|
||||||
gFFI.close();
|
gFFI.close();
|
||||||
SmartDialog.dismiss();
|
gFFI.dialogManager.dismissAll();
|
||||||
Wakelock.disable();
|
Wakelock.disable();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
@ -60,7 +61,9 @@ class _FileManagerPageState extends State<FileManagerPage> {
|
|||||||
backgroundColor: MyTheme.grayBg,
|
backgroundColor: MyTheme.grayBg,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: Row(children: [
|
leading: Row(children: [
|
||||||
IconButton(icon: Icon(Icons.close), onPressed: clientClose),
|
IconButton(
|
||||||
|
icon: Icon(Icons.close),
|
||||||
|
onPressed: () => clientClose(gFFI.dialogManager)),
|
||||||
]),
|
]),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
title: ToggleSwitch(
|
title: ToggleSwitch(
|
||||||
@ -141,8 +144,8 @@ class _FileManagerPageState extends State<FileManagerPage> {
|
|||||||
model.toggleSelectMode();
|
model.toggleSelectMode();
|
||||||
} else if (v == "folder") {
|
} else if (v == "folder") {
|
||||||
final name = TextEditingController();
|
final name = TextEditingController();
|
||||||
DialogManager.show(
|
gFFI.dialogManager
|
||||||
(setState, close) => CustomAlertDialog(
|
.show((setState, close) => CustomAlertDialog(
|
||||||
title: Text(translate("Create Folder")),
|
title: Text(translate("Create Folder")),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hbb/mobile/widgets/gesture_help.dart';
|
import 'package:flutter_hbb/mobile/widgets/gesture_help.dart';
|
||||||
import 'package:flutter_hbb/models/chat_model.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:provider/provider.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
|
||||||
@ -51,7 +50,8 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
gFFI.connect(widget.id);
|
gFFI.connect(widget.id);
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
|
||||||
showLoading(translate('Connecting...'));
|
gFFI.dialogManager
|
||||||
|
.showLoading(translate('Connecting...'), cancelToClose: true);
|
||||||
_interval =
|
_interval =
|
||||||
Timer.periodic(Duration(milliseconds: 30), (timer) => interval());
|
Timer.periodic(Duration(milliseconds: 30), (timer) => interval());
|
||||||
});
|
});
|
||||||
@ -71,7 +71,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
gFFI.close();
|
gFFI.close();
|
||||||
_interval?.cancel();
|
_interval?.cancel();
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
SmartDialog.dismiss();
|
gFFI.dialogManager.dismissAll();
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
|
||||||
overlays: SystemUiOverlay.values);
|
overlays: SystemUiOverlay.values);
|
||||||
Wakelock.disable();
|
Wakelock.disable();
|
||||||
@ -226,7 +226,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
|
|
||||||
return WillPopScope(
|
return WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
clientClose();
|
clientClose(gFFI.dialogManager);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: getRawPointerAndKeyBody(
|
child: getRawPointerAndKeyBody(
|
||||||
@ -401,7 +401,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
icon: Icon(Icons.clear),
|
icon: Icon(Icons.clear),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
clientClose();
|
clientClose(gFFI.dialogManager);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
] +
|
] +
|
||||||
@ -411,7 +411,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
icon: Icon(Icons.tv),
|
icon: Icon(Icons.tv),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() => _showEdit = false);
|
setState(() => _showEdit = false);
|
||||||
showOptions(widget.id);
|
showOptions(widget.id, gFFI.dialogManager);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
] +
|
] +
|
||||||
@ -671,7 +671,7 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
showSetOSPassword(id, false);
|
showSetOSPassword(id, false, gFFI.dialogManager);
|
||||||
},
|
},
|
||||||
child: Icon(Icons.edit, color: MyTheme.accent),
|
child: Icon(Icons.edit, color: MyTheme.accent),
|
||||||
)
|
)
|
||||||
@ -739,12 +739,12 @@ class _RemotePageState extends State<RemotePage> {
|
|||||||
if (password != null) {
|
if (password != null) {
|
||||||
bind.sessionInputOsPassword(id: widget.id, value: password);
|
bind.sessionInputOsPassword(id: widget.id, value: password);
|
||||||
} else {
|
} else {
|
||||||
showSetOSPassword(id, true);
|
showSetOSPassword(id, true, gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
} else if (value == 'reset_canvas') {
|
} else if (value == 'reset_canvas') {
|
||||||
gFFI.cursorModel.reset();
|
gFFI.cursorModel.reset();
|
||||||
} else if (value == 'restart') {
|
} else if (value == 'restart') {
|
||||||
showRestartRemoteDevice(pi, widget.id);
|
showRestartRemoteDevice(pi, widget.id, gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
@ -1008,7 +1008,7 @@ class QualityMonitor extends StatelessWidget {
|
|||||||
: SizedBox.shrink())));
|
: SizedBox.shrink())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void showOptions(String id) async {
|
void showOptions(String id, OverlayDialogManager dialogManager) async {
|
||||||
String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced';
|
String quality = await bind.getSessionImageQuality(id: id) ?? 'balanced';
|
||||||
if (quality == '') quality = 'balanced';
|
if (quality == '') quality = 'balanced';
|
||||||
String viewStyle =
|
String viewStyle =
|
||||||
@ -1026,7 +1026,7 @@ void showOptions(String id) async {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
if (i == cur) return;
|
if (i == cur) return;
|
||||||
bind.sessionSwitchDisplay(id: id, value: i);
|
bind.sessionSwitchDisplay(id: id, value: i);
|
||||||
SmartDialog.dismiss();
|
gFFI.dialogManager.dismissAll();
|
||||||
},
|
},
|
||||||
child: Ink(
|
child: Ink(
|
||||||
width: 40,
|
width: 40,
|
||||||
@ -1051,7 +1051,7 @@ void showOptions(String id) async {
|
|||||||
}
|
}
|
||||||
final perms = gFFI.ffiModel.permissions;
|
final perms = gFFI.ffiModel.permissions;
|
||||||
|
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
final more = <Widget>[];
|
final more = <Widget>[];
|
||||||
if (perms['audio'] != false) {
|
if (perms['audio'] != false) {
|
||||||
more.add(getToggle(id, setState, 'disable-audio', 'Mute'));
|
more.add(getToggle(id, setState, 'disable-audio', 'Mute'));
|
||||||
@ -1107,9 +1107,10 @@ void showOptions(String id) async {
|
|||||||
}, clickMaskDismiss: true, backDismiss: true);
|
}, clickMaskDismiss: true, backDismiss: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showRestartRemoteDevice(PeerInfo pi, String id) async {
|
void showRestartRemoteDevice(
|
||||||
|
PeerInfo pi, String id, OverlayDialogManager dialogManager) async {
|
||||||
final res =
|
final res =
|
||||||
await DialogManager.show<bool>((setState, close) => CustomAlertDialog(
|
await dialogManager.show<bool>((setState, close) => CustomAlertDialog(
|
||||||
title: Row(children: [
|
title: Row(children: [
|
||||||
Icon(Icons.warning_amber_sharp,
|
Icon(Icons.warning_amber_sharp,
|
||||||
color: Colors.redAccent, size: 28),
|
color: Colors.redAccent, size: 28),
|
||||||
@ -1128,12 +1129,13 @@ void showRestartRemoteDevice(PeerInfo pi, String id) async {
|
|||||||
if (res == true) bind.sessionRestartRemoteDevice(id: id);
|
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();
|
final controller = TextEditingController();
|
||||||
var password = await bind.getSessionOption(id: id, arg: "os-password") ?? "";
|
var password = await bind.getSessionOption(id: id, arg: "os-password") ?? "";
|
||||||
var autoLogin = await bind.getSessionOption(id: id, arg: "auto-login") != "";
|
var autoLogin = await bind.getSessionOption(id: id, arg: "auto-login") != "";
|
||||||
controller.text = password;
|
controller.text = password;
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('OS Password')),
|
title: Text(translate('OS Password')),
|
||||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
|
@ -63,7 +63,7 @@ class _ScanPageState extends State<ScanPage> {
|
|||||||
var result = reader.decode(bitmap);
|
var result = reader.decode(bitmap);
|
||||||
showServerSettingFromQr(result.text);
|
showServerSettingFromQr(result.text);
|
||||||
} catch (e) {
|
} 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) {
|
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
|
||||||
if (!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 {
|
void showServerSettingFromQr(String data) async {
|
||||||
backToHome();
|
backToHomePage();
|
||||||
await controller?.pauseCamera();
|
await controller?.pauseCamera();
|
||||||
if (!data.startsWith('config=')) {
|
if (!data.startsWith('config=')) {
|
||||||
showToast('Invalid QR code');
|
gFFI.dialogManager.showToast('Invalid QR code');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -144,16 +144,16 @@ class _ScanPageState extends State<ScanPage> {
|
|||||||
var key = values['key'] != null ? values['key'] as String : '';
|
var key = values['key'] != null ? values['key'] as String : '';
|
||||||
var api = values['api'] != null ? values['api'] as String : '';
|
var api = values['api'] != null ? values['api'] as String : '';
|
||||||
Timer(Duration(milliseconds: 60), () {
|
Timer(Duration(milliseconds: 60), () {
|
||||||
showServerSettingsWithValue(host, '', key, api);
|
showServerSettingsWithValue(host, '', key, api, gFFI.dialogManager);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showToast('Invalid QR code');
|
gFFI.dialogManager.showToast('Invalid QR code');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showServerSettingsWithValue(
|
void showServerSettingsWithValue(String id, String relay, String key,
|
||||||
String id, String relay, String key, String api) async {
|
String api, OverlayDialogManager dialogManager) async {
|
||||||
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
|
Map<String, dynamic> oldOptions = jsonDecode(await bind.mainGetOptions());
|
||||||
String id0 = oldOptions['custom-rendezvous-server'] ?? "";
|
String id0 = oldOptions['custom-rendezvous-server'] ?? "";
|
||||||
String relay0 = oldOptions['relay-server'] ?? "";
|
String relay0 = oldOptions['relay-server'] ?? "";
|
||||||
@ -168,7 +168,7 @@ void showServerSettingsWithValue(
|
|||||||
String? relayServerMsg;
|
String? relayServerMsg;
|
||||||
String? apiServerMsg;
|
String? apiServerMsg;
|
||||||
|
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
Future<bool> validate() async {
|
Future<bool> validate() async {
|
||||||
if (idController.text != id) {
|
if (idController.text != id) {
|
||||||
final res = await validateAsync(idController.text);
|
final res = await validateAsync(idController.text);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/mobile/widgets/dialog.dart';
|
import 'package:flutter_hbb/mobile/widgets/dialog.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
@ -90,9 +89,9 @@ class ServerPage extends StatefulWidget implements PageShape {
|
|||||||
if (value == "changeID") {
|
if (value == "changeID") {
|
||||||
// TODO
|
// TODO
|
||||||
} else if (value == "setPermanentPassword") {
|
} else if (value == "setPermanentPassword") {
|
||||||
setPermanentPasswordDialog();
|
setPermanentPasswordDialog(gFFI.dialogManager);
|
||||||
} else if (value == "setTemporaryPasswordLength") {
|
} else if (value == "setTemporaryPasswordLength") {
|
||||||
setTemporaryPasswordLengthDialog();
|
setTemporaryPasswordLengthDialog(gFFI.dialogManager);
|
||||||
} else if (value == kUsePermanentPassword ||
|
} else if (value == kUsePermanentPassword ||
|
||||||
value == kUseTemporaryPassword ||
|
value == kUseTemporaryPassword ||
|
||||||
value == kUseBothPasswords) {
|
value == kUseBothPasswords) {
|
||||||
@ -522,7 +521,7 @@ void toAndroidChannelInit() {
|
|||||||
switch (method) {
|
switch (method) {
|
||||||
case "start_capture":
|
case "start_capture":
|
||||||
{
|
{
|
||||||
SmartDialog.dismiss();
|
gFFI.dialogManager.dismissAll();
|
||||||
gFFI.serverModel.updateClientState();
|
gFFI.serverModel.updateClientState();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -119,8 +119,8 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
if (v) {
|
if (v) {
|
||||||
PermissionManager.request("ignore_battery_optimizations");
|
PermissionManager.request("ignore_battery_optimizations");
|
||||||
} else {
|
} else {
|
||||||
final res = await DialogManager.show<bool>(
|
final res = await gFFI.dialogManager
|
||||||
(setState, close) => CustomAlertDialog(
|
.show<bool>((setState, close) => CustomAlertDialog(
|
||||||
title: Text(translate("Open System Setting")),
|
title: Text(translate("Open System Setting")),
|
||||||
content: Text(translate(
|
content: Text(translate(
|
||||||
"android_open_battery_optimizations_tip")),
|
"android_open_battery_optimizations_tip")),
|
||||||
@ -153,9 +153,9 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
leading: Icon(Icons.person),
|
leading: Icon(Icons.person),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
showLogin();
|
showLogin(gFFI.dialogManager);
|
||||||
} else {
|
} else {
|
||||||
logout();
|
logout(gFFI.dialogManager);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -166,13 +166,13 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
title: Text(translate('ID/Relay Server')),
|
title: Text(translate('ID/Relay Server')),
|
||||||
leading: Icon(Icons.cloud),
|
leading: Icon(Icons.cloud),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
showServerSettings();
|
showServerSettings(gFFI.dialogManager);
|
||||||
}),
|
}),
|
||||||
SettingsTile.navigation(
|
SettingsTile.navigation(
|
||||||
title: Text(translate('Language')),
|
title: Text(translate('Language')),
|
||||||
leading: Icon(Icons.translate),
|
leading: Icon(Icons.translate),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
showLanguageSettings();
|
showLanguageSettings(gFFI.dialogManager);
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
SettingsSection(
|
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());
|
Map<String, dynamic> options = jsonDecode(await bind.mainGetOptions());
|
||||||
String id = options['custom-rendezvous-server'] ?? "";
|
String id = options['custom-rendezvous-server'] ?? "";
|
||||||
String relay = options['relay-server'] ?? "";
|
String relay = options['relay-server'] ?? "";
|
||||||
String api = options['api-server'] ?? "";
|
String api = options['api-server'] ?? "";
|
||||||
String key = options['key'] ?? "";
|
String key = options['key'] ?? "";
|
||||||
showServerSettingsWithValue(id, relay, key, api);
|
showServerSettingsWithValue(id, relay, key, api, dialogManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showLanguageSettings() async {
|
void showLanguageSettings(OverlayDialogManager dialogManager) async {
|
||||||
try {
|
try {
|
||||||
final langs = json.decode(await bind.mainGetLangs()) as List<dynamic>;
|
final langs = json.decode(await bind.mainGetLangs()) as List<dynamic>;
|
||||||
var lang = await bind.mainGetLocalOption(key: "lang");
|
var lang = await bind.mainGetLocalOption(key: "lang");
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
final setLang = (v) {
|
final setLang = (v) {
|
||||||
if (lang != v) {
|
if (lang != v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -246,8 +246,8 @@ void showLanguageSettings() async {
|
|||||||
} catch (_e) {}
|
} catch (_e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showAbout() {
|
void showAbout(OverlayDialogManager dialogManager) {
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('About') + ' RustDesk'),
|
title: Text(translate('About') + ' RustDesk'),
|
||||||
content: Wrap(direction: Axis.vertical, spacing: 12, children: [
|
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");
|
final token = await bind.mainGetOption(key: "access_token");
|
||||||
if (token == '') return;
|
if (token == '') return;
|
||||||
final url = getUrl();
|
final url = getUrl();
|
||||||
@ -363,7 +363,7 @@ void logout() async {
|
|||||||
},
|
},
|
||||||
body: json.encode(body));
|
body: json.encode(body));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showToast('Failed to access $url');
|
dialogManager.showToast('Failed to access $url');
|
||||||
}
|
}
|
||||||
resetToken();
|
resetToken();
|
||||||
}
|
}
|
||||||
@ -396,12 +396,12 @@ Future<String> getUrl() async {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showLogin() {
|
void showLogin(OverlayDialogManager dialogManager) {
|
||||||
final passwordController = TextEditingController();
|
final passwordController = TextEditingController();
|
||||||
final nameController = TextEditingController();
|
final nameController = TextEditingController();
|
||||||
var loading = false;
|
var loading = false;
|
||||||
var error = '';
|
var error = '';
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('Login')),
|
title: Text(translate('Login')),
|
||||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
|
@ -1,32 +1,31 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
|
|
||||||
import '../../common.dart';
|
import '../../common.dart';
|
||||||
import '../../models/platform_model.dart';
|
import '../../models/platform_model.dart';
|
||||||
|
|
||||||
void clientClose() {
|
void clientClose(OverlayDialogManager dialogManager) {
|
||||||
msgBox('', 'Close', 'Are you sure to close the connection?');
|
msgBox('', 'Close', 'Are you sure to close the connection?', dialogManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SEC1 = Duration(seconds: 1);
|
const SEC1 = Duration(seconds: 1);
|
||||||
void showSuccess({Duration duration = SEC1}) {
|
void showSuccess({Duration duration = SEC1}) {
|
||||||
SmartDialog.dismiss();
|
// TODO
|
||||||
showToast(translate("Successful"), duration: SEC1);
|
// showToast(translate("Successful"), duration: SEC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showError({Duration duration = SEC1}) {
|
void showError({Duration duration = SEC1}) {
|
||||||
SmartDialog.dismiss();
|
// TODO
|
||||||
showToast(translate("Error"), duration: SEC1);
|
// showToast(translate("Error"), duration: SEC1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPermanentPasswordDialog() async {
|
void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
|
||||||
final pw = await bind.mainGetPermanentPassword();
|
final pw = await bind.mainGetPermanentPassword();
|
||||||
final p0 = TextEditingController(text: pw);
|
final p0 = TextEditingController(text: pw);
|
||||||
final p1 = TextEditingController(text: pw);
|
final p1 = TextEditingController(text: pw);
|
||||||
var validateLength = false;
|
var validateLength = false;
|
||||||
var validateSame = false;
|
var validateSame = false;
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('Set your own password')),
|
title: Text(translate('Set your own password')),
|
||||||
content: Form(
|
content: Form(
|
||||||
@ -86,7 +85,7 @@ void setPermanentPasswordDialog() async {
|
|||||||
onPressed: (validateLength && validateSame)
|
onPressed: (validateLength && validateSame)
|
||||||
? () async {
|
? () async {
|
||||||
close();
|
close();
|
||||||
showLoading(translate("Waiting"));
|
dialogManager.showLoading(translate("Waiting"));
|
||||||
if (await gFFI.serverModel.setPermanentPassword(p0.text)) {
|
if (await gFFI.serverModel.setPermanentPassword(p0.text)) {
|
||||||
showSuccess();
|
showSuccess();
|
||||||
} else {
|
} else {
|
||||||
@ -101,13 +100,14 @@ void setPermanentPasswordDialog() async {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTemporaryPasswordLengthDialog() async {
|
void setTemporaryPasswordLengthDialog(
|
||||||
|
OverlayDialogManager dialogManager) async {
|
||||||
List<String> lengths = ['6', '8', '10'];
|
List<String> lengths = ['6', '8', '10'];
|
||||||
String length = await bind.mainGetOption(key: "temporary-password-length");
|
String length = await bind.mainGetOption(key: "temporary-password-length");
|
||||||
var index = lengths.indexOf(length);
|
var index = lengths.indexOf(length);
|
||||||
if (index < 0) index = 0;
|
if (index < 0) index = 0;
|
||||||
length = lengths[index];
|
length = lengths[index];
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.show((setState, close) {
|
||||||
final setLength = (newValue) {
|
final setLength = (newValue) {
|
||||||
final oldValue = length;
|
final oldValue = length;
|
||||||
if (oldValue == newValue) return;
|
if (oldValue == newValue) return;
|
||||||
@ -133,10 +133,11 @@ void setTemporaryPasswordLengthDialog() async {
|
|||||||
}, backDismiss: true, clickMaskDismiss: true);
|
}, backDismiss: true, clickMaskDismiss: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterPasswordDialog(String id) async {
|
void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async {
|
||||||
final controller = TextEditingController();
|
final controller = TextEditingController();
|
||||||
var remember = await bind.getSessionRemember(id: id) ?? false;
|
var remember = await bind.getSessionRemember(id: id) ?? false;
|
||||||
DialogManager.show((setState, close) {
|
dialogManager.dismissAll();
|
||||||
|
dialogManager.show((setState, close) {
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('Password Required')),
|
title: Text(translate('Password Required')),
|
||||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
@ -161,7 +162,7 @@ void enterPasswordDialog(String id) async {
|
|||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
close();
|
close();
|
||||||
backToHome();
|
backToHomePage();
|
||||||
},
|
},
|
||||||
child: Text(translate('Cancel')),
|
child: Text(translate('Cancel')),
|
||||||
),
|
),
|
||||||
@ -172,7 +173,8 @@ void enterPasswordDialog(String id) async {
|
|||||||
if (text == '') return;
|
if (text == '') return;
|
||||||
gFFI.login(id, text, remember);
|
gFFI.login(id, text, remember);
|
||||||
close();
|
close();
|
||||||
showLoading(translate('Logging in...'));
|
dialogManager.showLoading(translate('Logging in...'),
|
||||||
|
cancelToClose: true);
|
||||||
},
|
},
|
||||||
child: Text(translate('OK')),
|
child: Text(translate('OK')),
|
||||||
),
|
),
|
||||||
@ -181,8 +183,8 @@ void enterPasswordDialog(String id) async {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void wrongPasswordDialog(String id) {
|
void wrongPasswordDialog(String id, OverlayDialogManager dialogManager) {
|
||||||
DialogManager.show((setState, close) => CustomAlertDialog(
|
dialogManager.show((setState, close) => CustomAlertDialog(
|
||||||
title: Text(translate('Wrong Password')),
|
title: Text(translate('Wrong Password')),
|
||||||
content: Text(translate('Do you want to enter again?')),
|
content: Text(translate('Do you want to enter again?')),
|
||||||
actions: [
|
actions: [
|
||||||
@ -190,14 +192,14 @@ void wrongPasswordDialog(String id) {
|
|||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
close();
|
close();
|
||||||
backToHome();
|
backToHomePage();
|
||||||
},
|
},
|
||||||
child: Text(translate('Cancel')),
|
child: Text(translate('Cancel')),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
enterPasswordDialog(id);
|
enterPasswordDialog(id, dialogManager);
|
||||||
},
|
},
|
||||||
child: Text(translate('Retry')),
|
child: Text(translate('Retry')),
|
||||||
),
|
),
|
||||||
@ -239,8 +241,8 @@ class _PasswordWidgetState extends State<PasswordWidget> {
|
|||||||
//This will obscure text dynamically
|
//This will obscure text dynamically
|
||||||
keyboardType: TextInputType.visiblePassword,
|
keyboardType: TextInputType.visiblePassword,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: Translator.call('Password'),
|
labelText: translate('Password'),
|
||||||
hintText: Translator.call('Enter your password'),
|
hintText: translate('Enter your password'),
|
||||||
// Here is key idea
|
// Here is key idea
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
|
@ -4,7 +4,6 @@ import 'dart:convert';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/common.dart';
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/mobile/pages/file_manager_page.dart';
|
import 'package:flutter_hbb/mobile/pages/file_manager_page.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:path/path.dart' as Path;
|
import 'package:path/path.dart' as Path;
|
||||||
|
|
||||||
@ -126,9 +125,9 @@ class FileModel extends ChangeNotifier {
|
|||||||
|
|
||||||
final _jobResultListener = JobResultListener<Map<String, dynamic>>();
|
final _jobResultListener = JobResultListener<Map<String, dynamic>>();
|
||||||
|
|
||||||
final WeakReference<FFI> _ffi;
|
final WeakReference<FFI> parent;
|
||||||
|
|
||||||
FileModel(this._ffi);
|
FileModel(this.parent);
|
||||||
|
|
||||||
toggleSelectMode() {
|
toggleSelectMode() {
|
||||||
if (jobState == JobState.inProgress) {
|
if (jobState == JobState.inProgress) {
|
||||||
@ -275,7 +274,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
need_override = true;
|
need_override = true;
|
||||||
}
|
}
|
||||||
bind.sessionSetConfirmOverrideFile(
|
bind.sessionSetConfirmOverrideFile(
|
||||||
id: _ffi.target?.id ?? "",
|
id: parent.target?.id ?? "",
|
||||||
actId: id,
|
actId: id,
|
||||||
fileNum: int.parse(evt['file_num']),
|
fileNum: int.parse(evt['file_num']),
|
||||||
needOverride: need_override,
|
needOverride: need_override,
|
||||||
@ -292,22 +291,22 @@ class FileModel extends ChangeNotifier {
|
|||||||
onReady() async {
|
onReady() async {
|
||||||
_localOption.home = await bind.mainGetHomeDir();
|
_localOption.home = await bind.mainGetHomeDir();
|
||||||
_localOption.showHidden = (await bind.sessionGetPeerOption(
|
_localOption.showHidden = (await bind.sessionGetPeerOption(
|
||||||
id: _ffi.target?.id ?? "", name: "local_show_hidden"))
|
id: parent.target?.id ?? "", name: "local_show_hidden"))
|
||||||
.isNotEmpty;
|
.isNotEmpty;
|
||||||
|
|
||||||
_remoteOption.showHidden = (await bind.sessionGetPeerOption(
|
_remoteOption.showHidden = (await bind.sessionGetPeerOption(
|
||||||
id: _ffi.target?.id ?? "", name: "remote_show_hidden"))
|
id: parent.target?.id ?? "", name: "remote_show_hidden"))
|
||||||
.isNotEmpty;
|
.isNotEmpty;
|
||||||
_remoteOption.isWindows = _ffi.target?.ffiModel.pi.platform == "Windows";
|
_remoteOption.isWindows = parent.target?.ffiModel.pi.platform == "Windows";
|
||||||
|
|
||||||
debugPrint("remote platform: ${_ffi.target?.ffiModel.pi.platform}");
|
debugPrint("remote platform: ${parent.target?.ffiModel.pi.platform}");
|
||||||
|
|
||||||
await Future.delayed(Duration(milliseconds: 100));
|
await Future.delayed(Duration(milliseconds: 100));
|
||||||
|
|
||||||
final local = (await bind.sessionGetPeerOption(
|
final local = (await bind.sessionGetPeerOption(
|
||||||
id: _ffi.target?.id ?? "", name: "local_dir"));
|
id: parent.target?.id ?? "", name: "local_dir"));
|
||||||
final remote = (await bind.sessionGetPeerOption(
|
final remote = (await bind.sessionGetPeerOption(
|
||||||
id: _ffi.target?.id ?? "", name: "remote_dir"));
|
id: parent.target?.id ?? "", name: "remote_dir"));
|
||||||
openDirectory(local.isEmpty ? _localOption.home : local, isLocal: true);
|
openDirectory(local.isEmpty ? _localOption.home : local, isLocal: true);
|
||||||
openDirectory(remote.isEmpty ? _remoteOption.home : remote, isLocal: false);
|
openDirectory(remote.isEmpty ? _remoteOption.home : remote, isLocal: false);
|
||||||
await Future.delayed(Duration(seconds: 1));
|
await Future.delayed(Duration(seconds: 1));
|
||||||
@ -318,11 +317,11 @@ class FileModel extends ChangeNotifier {
|
|||||||
openDirectory(_remoteOption.home, isLocal: false);
|
openDirectory(_remoteOption.home, isLocal: false);
|
||||||
}
|
}
|
||||||
// load last transfer jobs
|
// load last transfer jobs
|
||||||
await bind.sessionLoadLastTransferJobs(id: '${_ffi.target?.id}');
|
await bind.sessionLoadLastTransferJobs(id: '${parent.target?.id}');
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose() {
|
onClose() {
|
||||||
SmartDialog.dismiss();
|
parent.target?.dialogManager.dismissAll();
|
||||||
jobReset();
|
jobReset();
|
||||||
|
|
||||||
// save config
|
// save config
|
||||||
@ -332,7 +331,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
msgMap["local_show_hidden"] = _localOption.showHidden ? "Y" : "";
|
msgMap["local_show_hidden"] = _localOption.showHidden ? "Y" : "";
|
||||||
msgMap["remote_dir"] = _currentRemoteDir.path;
|
msgMap["remote_dir"] = _currentRemoteDir.path;
|
||||||
msgMap["remote_show_hidden"] = _remoteOption.showHidden ? "Y" : "";
|
msgMap["remote_show_hidden"] = _remoteOption.showHidden ? "Y" : "";
|
||||||
final id = _ffi.target?.id ?? "";
|
final id = parent.target?.id ?? "";
|
||||||
for (final msg in msgMap.entries) {
|
for (final msg in msgMap.entries) {
|
||||||
bind.sessionPeerOption(id: id, name: msg.key, value: msg.value);
|
bind.sessionPeerOption(id: id, name: msg.key, value: msg.value);
|
||||||
}
|
}
|
||||||
@ -419,7 +418,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
..id = jobId
|
..id = jobId
|
||||||
..isRemote = isRemote);
|
..isRemote = isRemote);
|
||||||
bind.sessionSendFiles(
|
bind.sessionSendFiles(
|
||||||
id: '${_ffi.target?.id}',
|
id: '${parent.target?.id}',
|
||||||
actId: _jobId,
|
actId: _jobId,
|
||||||
path: from.path,
|
path: from.path,
|
||||||
to: PathUtil.join(toPath, from.name, isWindows),
|
to: PathUtil.join(toPath, from.name, isWindows),
|
||||||
@ -477,14 +476,14 @@ class FileModel extends ChangeNotifier {
|
|||||||
entries = [item];
|
entries = [item];
|
||||||
} else if (item.isDirectory) {
|
} else if (item.isDirectory) {
|
||||||
title = translate("Not an empty directory");
|
title = translate("Not an empty directory");
|
||||||
showLoading(translate("Waiting"));
|
parent.target?.dialogManager.showLoading(translate("Waiting"));
|
||||||
final fd = await _fileFetcher.fetchDirectoryRecursive(
|
final fd = await _fileFetcher.fetchDirectoryRecursive(
|
||||||
_jobId, item.path, items.isLocal!, true);
|
_jobId, item.path, items.isLocal!, true);
|
||||||
if (fd.path.isEmpty) {
|
if (fd.path.isEmpty) {
|
||||||
fd.path = item.path;
|
fd.path = item.path;
|
||||||
}
|
}
|
||||||
fd.format(isWindows);
|
fd.format(isWindows);
|
||||||
SmartDialog.dismiss();
|
parent.target?.dialogManager.dismissAll();
|
||||||
if (fd.entries.isEmpty) {
|
if (fd.entries.isEmpty) {
|
||||||
final confirm = await showRemoveDialog(
|
final confirm = await showRemoveDialog(
|
||||||
translate(
|
translate(
|
||||||
@ -543,7 +542,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
|
|
||||||
Future<bool?> showRemoveDialog(
|
Future<bool?> showRemoveDialog(
|
||||||
String title, String content, bool showCheckbox) async {
|
String title, String content, bool showCheckbox) async {
|
||||||
return await DialogManager.show<bool>(
|
return await parent.target?.dialogManager.show<bool>(
|
||||||
(setState, Function(bool v) close) => CustomAlertDialog(
|
(setState, Function(bool v) close) => CustomAlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -594,7 +593,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
Future<bool?> showFileConfirmDialog(
|
Future<bool?> showFileConfirmDialog(
|
||||||
String title, String content, bool showCheckbox) async {
|
String title, String content, bool showCheckbox) async {
|
||||||
fileConfirmCheckboxRemember = false;
|
fileConfirmCheckboxRemember = false;
|
||||||
return await DialogManager.show<bool?>(
|
return await parent.target?.dialogManager.show<bool?>(
|
||||||
(setState, Function(bool? v) close) => CustomAlertDialog(
|
(setState, Function(bool? v) close) => CustomAlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -648,7 +647,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
|
|
||||||
sendRemoveFile(String path, int fileNum, bool isLocal) {
|
sendRemoveFile(String path, int fileNum, bool isLocal) {
|
||||||
bind.sessionRemoveFile(
|
bind.sessionRemoveFile(
|
||||||
id: '${_ffi.target?.id}',
|
id: '${parent.target?.id}',
|
||||||
actId: _jobId,
|
actId: _jobId,
|
||||||
path: path,
|
path: path,
|
||||||
isRemote: !isLocal,
|
isRemote: !isLocal,
|
||||||
@ -657,7 +656,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
|
|
||||||
sendRemoveEmptyDir(String path, int fileNum, bool isLocal) {
|
sendRemoveEmptyDir(String path, int fileNum, bool isLocal) {
|
||||||
bind.sessionRemoveAllEmptyDirs(
|
bind.sessionRemoveAllEmptyDirs(
|
||||||
id: '${_ffi.target?.id}',
|
id: '${parent.target?.id}',
|
||||||
actId: _jobId,
|
actId: _jobId,
|
||||||
path: path,
|
path: path,
|
||||||
isRemote: !isLocal);
|
isRemote: !isLocal);
|
||||||
@ -667,14 +666,14 @@ class FileModel extends ChangeNotifier {
|
|||||||
isLocal = isLocal ?? this.isLocal;
|
isLocal = isLocal ?? this.isLocal;
|
||||||
_jobId++;
|
_jobId++;
|
||||||
bind.sessionCreateDir(
|
bind.sessionCreateDir(
|
||||||
id: '${_ffi.target?.id}',
|
id: '${parent.target?.id}',
|
||||||
actId: _jobId,
|
actId: _jobId,
|
||||||
path: path,
|
path: path,
|
||||||
isRemote: !isLocal);
|
isRemote: !isLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelJob(int id) async {
|
cancelJob(int id) async {
|
||||||
bind.sessionCancelJob(id: '${_ffi.target?.id}', actId: id);
|
bind.sessionCancelJob(id: '${parent.target?.id}', actId: id);
|
||||||
jobReset();
|
jobReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,7 +700,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initFileFetcher() {
|
initFileFetcher() {
|
||||||
_fileFetcher.id = _ffi.target?.id;
|
_fileFetcher.id = parent.target?.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateFolderFiles(Map<String, dynamic> evt) {
|
void updateFolderFiles(Map<String, dynamic> evt) {
|
||||||
@ -742,7 +741,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
..state = JobState.paused;
|
..state = JobState.paused;
|
||||||
jobTable.add(jobProgress);
|
jobTable.add(jobProgress);
|
||||||
bind.sessionAddJob(
|
bind.sessionAddJob(
|
||||||
id: '${_ffi.target?.id}',
|
id: '${parent.target?.id}',
|
||||||
isRemote: isRemote,
|
isRemote: isRemote,
|
||||||
includeHidden: showHidden,
|
includeHidden: showHidden,
|
||||||
actId: currJobId,
|
actId: currJobId,
|
||||||
@ -757,7 +756,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
if (jobIndex != -1) {
|
if (jobIndex != -1) {
|
||||||
final job = jobTable[jobIndex];
|
final job = jobTable[jobIndex];
|
||||||
bind.sessionResumeJob(
|
bind.sessionResumeJob(
|
||||||
id: '${_ffi.target?.id}', actId: job.id, isRemote: job.isRemote);
|
id: '${parent.target?.id}', actId: job.id, isRemote: job.isRemote);
|
||||||
job.state = JobState.inProgress;
|
job.state = JobState.inProgress;
|
||||||
} else {
|
} else {
|
||||||
debugPrint("jobId ${jobId} is not exists");
|
debugPrint("jobId ${jobId} is not exists");
|
||||||
|
@ -13,7 +13,6 @@ import 'package:flutter_hbb/models/chat_model.dart';
|
|||||||
import 'package:flutter_hbb/models/file_model.dart';
|
import 'package:flutter_hbb/models/file_model.dart';
|
||||||
import 'package:flutter_hbb/models/server_model.dart';
|
import 'package:flutter_hbb/models/server_model.dart';
|
||||||
import 'package:flutter_hbb/models/user_model.dart';
|
import 'package:flutter_hbb/models/user_model.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
@ -60,7 +59,6 @@ class FfiModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FfiModel(this.parent) {
|
FfiModel(this.parent) {
|
||||||
Translator.call = translate;
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,32 +259,35 @@ class FfiModel with ChangeNotifier {
|
|||||||
|
|
||||||
/// Handle the message box event based on [evt] and [id].
|
/// Handle the message box event based on [evt] and [id].
|
||||||
void handleMsgBox(Map<String, dynamic> evt, String id) {
|
void handleMsgBox(Map<String, dynamic> evt, String id) {
|
||||||
|
if (parent.target == null) return;
|
||||||
|
final dialogManager = parent.target!.dialogManager;
|
||||||
var type = evt['type'];
|
var type = evt['type'];
|
||||||
var title = evt['title'];
|
var title = evt['title'];
|
||||||
var text = evt['text'];
|
var text = evt['text'];
|
||||||
if (type == 're-input-password') {
|
if (type == 're-input-password') {
|
||||||
wrongPasswordDialog(id);
|
wrongPasswordDialog(id, dialogManager);
|
||||||
} else if (type == 'input-password') {
|
} else if (type == 'input-password') {
|
||||||
enterPasswordDialog(id);
|
enterPasswordDialog(id, dialogManager);
|
||||||
} else if (type == 'restarting') {
|
} else if (type == 'restarting') {
|
||||||
showMsgBox(id, type, title, text, false, hasCancel: false);
|
showMsgBox(id, type, title, text, false, dialogManager, hasCancel: false);
|
||||||
} else {
|
} else {
|
||||||
var hasRetry = evt['hasRetry'] == 'true';
|
var hasRetry = evt['hasRetry'] == 'true';
|
||||||
showMsgBox(id, type, title, text, hasRetry);
|
showMsgBox(id, type, title, text, hasRetry, dialogManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show a message box with [type], [title] and [text].
|
/// Show a message box with [type], [title] and [text].
|
||||||
void showMsgBox(
|
void showMsgBox(String id, String type, String title, String text,
|
||||||
String id, String type, String title, String text, bool hasRetry,
|
bool hasRetry, OverlayDialogManager dialogManager,
|
||||||
{bool? hasCancel}) {
|
{bool? hasCancel}) {
|
||||||
msgBox(type, title, text, hasCancel: hasCancel);
|
msgBox(type, title, text, dialogManager, hasCancel: hasCancel);
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
if (hasRetry) {
|
if (hasRetry) {
|
||||||
_timer = Timer(Duration(seconds: _reconnects), () {
|
_timer = Timer(Duration(seconds: _reconnects), () {
|
||||||
bind.sessionReconnect(id: id);
|
bind.sessionReconnect(id: id);
|
||||||
clearPermissions();
|
clearPermissions();
|
||||||
showLoading(translate('Connecting...'));
|
dialogManager.showLoading(translate('Connecting...'),
|
||||||
|
cancelToClose: true);
|
||||||
});
|
});
|
||||||
_reconnects *= 2;
|
_reconnects *= 2;
|
||||||
} else {
|
} else {
|
||||||
@ -296,7 +297,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
|
|
||||||
/// Handle the peer info event based on [evt].
|
/// Handle the peer info event based on [evt].
|
||||||
void handlePeerInfo(Map<String, dynamic> evt, String peerId) async {
|
void handlePeerInfo(Map<String, dynamic> evt, String peerId) async {
|
||||||
SmartDialog.dismiss();
|
parent.target?.dialogManager.dismissAll();
|
||||||
_pi.version = evt['version'];
|
_pi.version = evt['version'];
|
||||||
_pi.username = evt['username'];
|
_pi.username = evt['username'];
|
||||||
_pi.hostname = evt['hostname'];
|
_pi.hostname = evt['hostname'];
|
||||||
@ -332,7 +333,9 @@ class FfiModel with ChangeNotifier {
|
|||||||
_display = _pi.displays[_pi.currentDisplay];
|
_display = _pi.displays[_pi.currentDisplay];
|
||||||
}
|
}
|
||||||
if (displays.length > 0) {
|
if (displays.length > 0) {
|
||||||
showLoading(translate('Connected, waiting for image...'));
|
parent.target?.dialogManager.showLoading(
|
||||||
|
translate('Connected, waiting for image...'),
|
||||||
|
cancelToClose: true);
|
||||||
_waitForImage = true;
|
_waitForImage = true;
|
||||||
_reconnects = 1;
|
_reconnects = 1;
|
||||||
}
|
}
|
||||||
@ -364,7 +367,7 @@ class ImageModel with ChangeNotifier {
|
|||||||
void onRgba(Uint8List rgba, double tabBarHeight) {
|
void onRgba(Uint8List rgba, double tabBarHeight) {
|
||||||
if (_waitForImage) {
|
if (_waitForImage) {
|
||||||
_waitForImage = false;
|
_waitForImage = false;
|
||||||
SmartDialog.dismiss();
|
parent.target?.dialogManager.dismissAll();
|
||||||
}
|
}
|
||||||
final pid = parent.target?.id;
|
final pid = parent.target?.id;
|
||||||
ui.decodeImageFromPixels(
|
ui.decodeImageFromPixels(
|
||||||
@ -874,16 +877,20 @@ class FFI {
|
|||||||
var alt = false;
|
var alt = false;
|
||||||
var command = false;
|
var command = false;
|
||||||
var version = "";
|
var version = "";
|
||||||
late final ImageModel imageModel;
|
|
||||||
late final FfiModel ffiModel;
|
/// dialogManager use late to ensure init after main page binding [globalKey]
|
||||||
late final CursorModel cursorModel;
|
late final dialogManager = OverlayDialogManager();
|
||||||
late final CanvasModel canvasModel;
|
|
||||||
late final ServerModel serverModel;
|
late final ImageModel imageModel; // session
|
||||||
late final ChatModel chatModel;
|
late final FfiModel ffiModel; // session
|
||||||
late final FileModel fileModel;
|
late final CursorModel cursorModel; // session
|
||||||
late final AbModel abModel;
|
late final CanvasModel canvasModel; // session
|
||||||
late final UserModel userModel;
|
late final ServerModel serverModel; // global
|
||||||
late final QualityMonitorModel qualityMonitorModel;
|
late final ChatModel chatModel; // session
|
||||||
|
late final FileModel fileModel; // session
|
||||||
|
late final AbModel abModel; // global
|
||||||
|
late final UserModel userModel; // global
|
||||||
|
late final QualityMonitorModel qualityMonitorModel; // session
|
||||||
|
|
||||||
FFI() {
|
FFI() {
|
||||||
this.imageModel = ImageModel(WeakReference(this));
|
this.imageModel = ImageModel(WeakReference(this));
|
||||||
|
@ -75,7 +75,7 @@ class PlatformFFI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String translate(String name, String locale) {
|
String translate(String name, String locale) {
|
||||||
if (_translate == null) return '';
|
if (_translate == null) return name;
|
||||||
var a = name.toNativeUtf8();
|
var a = name.toNativeUtf8();
|
||||||
var b = locale.toNativeUtf8();
|
var b = locale.toNativeUtf8();
|
||||||
var p = _translate!(a, b);
|
var p = _translate!(a, b);
|
||||||
|
@ -10,7 +10,7 @@ import '../common.dart';
|
|||||||
import '../mobile/pages/server_page.dart';
|
import '../mobile/pages/server_page.dart';
|
||||||
import 'model.dart';
|
import 'model.dart';
|
||||||
|
|
||||||
const loginDialogTag = "LOGIN";
|
const KLoginDialogTag = "LOGIN";
|
||||||
|
|
||||||
const kUseTemporaryPassword = "use-temporary-password";
|
const kUseTemporaryPassword = "use-temporary-password";
|
||||||
const kUsePermanentPassword = "use-permanent-password";
|
const kUsePermanentPassword = "use-permanent-password";
|
||||||
@ -206,8 +206,8 @@ class ServerModel with ChangeNotifier {
|
|||||||
/// Toggle the screen sharing service.
|
/// Toggle the screen sharing service.
|
||||||
toggleService() async {
|
toggleService() async {
|
||||||
if (_isStart) {
|
if (_isStart) {
|
||||||
final res =
|
final res = await parent.target?.dialogManager
|
||||||
await DialogManager.show<bool>((setState, close) => CustomAlertDialog(
|
.show<bool>((setState, close) => CustomAlertDialog(
|
||||||
title: Row(children: [
|
title: Row(children: [
|
||||||
Icon(Icons.warning_amber_sharp,
|
Icon(Icons.warning_amber_sharp,
|
||||||
color: Colors.redAccent, size: 28),
|
color: Colors.redAccent, size: 28),
|
||||||
@ -228,8 +228,8 @@ class ServerModel with ChangeNotifier {
|
|||||||
stopService();
|
stopService();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final res =
|
final res = await parent.target?.dialogManager
|
||||||
await DialogManager.show<bool>((setState, close) => CustomAlertDialog(
|
.show<bool>((setState, close) => CustomAlertDialog(
|
||||||
title: Row(children: [
|
title: Row(children: [
|
||||||
Icon(Icons.warning_amber_sharp,
|
Icon(Icons.warning_amber_sharp,
|
||||||
color: Colors.redAccent, size: 28),
|
color: Colors.redAccent, size: 28),
|
||||||
@ -272,7 +272,7 @@ class ServerModel with ChangeNotifier {
|
|||||||
Future<Null> stopService() async {
|
Future<Null> stopService() async {
|
||||||
_isStart = false;
|
_isStart = false;
|
||||||
// TODO
|
// TODO
|
||||||
parent.target?.serverModel.closeAll();
|
closeAll();
|
||||||
await parent.target?.invokeMethod("stop_service");
|
await parent.target?.invokeMethod("stop_service");
|
||||||
await bind.mainStopService();
|
await bind.mainStopService();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@ -370,7 +370,7 @@ class ServerModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showLoginDialog(Client client) {
|
void showLoginDialog(Client client) {
|
||||||
DialogManager.show(
|
parent.target?.dialogManager.show(
|
||||||
(setState, close) => CustomAlertDialog(
|
(setState, close) => CustomAlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
@ -442,7 +442,7 @@ class ServerModel with ChangeNotifier {
|
|||||||
void onClientAuthorized(Map<String, dynamic> evt) {
|
void onClientAuthorized(Map<String, dynamic> evt) {
|
||||||
try {
|
try {
|
||||||
final client = Client.fromJson(jsonDecode(evt['client']));
|
final client = Client.fromJson(jsonDecode(evt['client']));
|
||||||
DialogManager.dismissByTag(getLoginDialogTag(client.id));
|
parent.target?.dialogManager.dismissByTag(getLoginDialogTag(client.id));
|
||||||
_clients[client.id] = client;
|
_clients[client.id] = client;
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@ -454,7 +454,7 @@ class ServerModel with ChangeNotifier {
|
|||||||
final id = int.parse(evt['id'] as String);
|
final id = int.parse(evt['id'] as String);
|
||||||
if (_clients.containsKey(id)) {
|
if (_clients.containsKey(id)) {
|
||||||
_clients.remove(id);
|
_clients.remove(id);
|
||||||
DialogManager.dismissByTag(getLoginDialogTag(id));
|
parent.target?.dialogManager.dismissByTag(getLoginDialogTag(id));
|
||||||
parent.target?.invokeMethod("cancel_notification", id);
|
parent.target?.invokeMethod("cancel_notification", id);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@ -510,11 +510,11 @@ class Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getLoginDialogTag(int id) {
|
String getLoginDialogTag(int id) {
|
||||||
return loginDialogTag + id.toString();
|
return KLoginDialogTag + id.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
showInputWarnAlert(FFI ffi) {
|
showInputWarnAlert(FFI ffi) {
|
||||||
DialogManager.show((setState, close) => CustomAlertDialog(
|
ffi.dialogManager.show((setState, close) => CustomAlertDialog(
|
||||||
title: Text(translate("How to get Android input permission?")),
|
title: Text(translate("How to get Android input permission?")),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,7 @@ dependencies:
|
|||||||
zxing2: ^0.1.0
|
zxing2: ^0.1.0
|
||||||
image_picker: ^0.8.5
|
image_picker: ^0.8.5
|
||||||
image: ^3.1.3
|
image: ^3.1.3
|
||||||
flutter_smart_dialog: ^4.3.1
|
back_button_interceptor: ^6.0.1
|
||||||
flutter_rust_bridge:
|
flutter_rust_bridge:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge
|
url: https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge
|
||||||
|
Loading…
x
Reference in New Issue
Block a user