Merge pull request #3405 from NicKoehler/modern-dialog
Modernize dialogs
This commit is contained in:
commit
b9e5576cd5
flutter/lib
@ -174,6 +174,27 @@ class MyTheme {
|
|||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
hoverColor: Color.fromARGB(255, 224, 224, 224),
|
hoverColor: Color.fromARGB(255, 224, 224, 224),
|
||||||
scaffoldBackgroundColor: Color(0xFFFFFFFF),
|
scaffoldBackgroundColor: Color(0xFFFFFFFF),
|
||||||
|
dialogBackgroundColor: Color(0xFFFFFFFF),
|
||||||
|
dialogTheme: DialogTheme(
|
||||||
|
elevation: 15,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18.0),
|
||||||
|
side: BorderSide(
|
||||||
|
width: 1,
|
||||||
|
color: Color(0xFFEEEEEE),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
|
fillColor: Color(0xFFEEEEEE),
|
||||||
|
filled: true,
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: EdgeInsets.all(15),
|
||||||
|
border: UnderlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18),
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
textTheme: const TextTheme(
|
textTheme: const TextTheme(
|
||||||
titleLarge: TextStyle(fontSize: 19, color: Colors.black87),
|
titleLarge: TextStyle(fontSize: 19, color: Colors.black87),
|
||||||
titleSmall: TextStyle(fontSize: 14, color: Colors.black87),
|
titleSmall: TextStyle(fontSize: 14, color: Colors.black87),
|
||||||
@ -192,9 +213,48 @@ class MyTheme {
|
|||||||
splashFactory: isDesktop ? NoSplash.splashFactory : null,
|
splashFactory: isDesktop ? NoSplash.splashFactory : null,
|
||||||
textButtonTheme: isDesktop
|
textButtonTheme: isDesktop
|
||||||
? TextButtonThemeData(
|
? TextButtonThemeData(
|
||||||
style: ButtonStyle(splashFactory: NoSplash.splashFactory),
|
style: TextButton.styleFrom(
|
||||||
|
splashFactory: NoSplash.splashFactory,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: MyTheme.accent,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
backgroundColor: Color(
|
||||||
|
0xFFEEEEEE,
|
||||||
|
),
|
||||||
|
foregroundColor: Colors.black87,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
checkboxTheme: const CheckboxThemeData(
|
||||||
|
splashRadius: 0,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
listTileTheme: ListTileThemeData(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
colorScheme: ColorScheme.fromSwatch(
|
colorScheme: ColorScheme.fromSwatch(
|
||||||
primarySwatch: Colors.blue,
|
primarySwatch: Colors.blue,
|
||||||
).copyWith(
|
).copyWith(
|
||||||
@ -211,6 +271,27 @@ class MyTheme {
|
|||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
hoverColor: Color.fromARGB(255, 45, 46, 53),
|
hoverColor: Color.fromARGB(255, 45, 46, 53),
|
||||||
scaffoldBackgroundColor: Color(0xFF18191E),
|
scaffoldBackgroundColor: Color(0xFF18191E),
|
||||||
|
dialogBackgroundColor: Color(0xFF18191E),
|
||||||
|
dialogTheme: DialogTheme(
|
||||||
|
elevation: 15,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18.0),
|
||||||
|
side: BorderSide(
|
||||||
|
width: 1,
|
||||||
|
color: Color(0xFF24252B),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
|
fillColor: Color(0xFF24252B),
|
||||||
|
filled: true,
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: EdgeInsets.all(15),
|
||||||
|
border: UnderlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18),
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
textTheme: const TextTheme(
|
textTheme: const TextTheme(
|
||||||
titleLarge: TextStyle(fontSize: 19),
|
titleLarge: TextStyle(fontSize: 19),
|
||||||
titleSmall: TextStyle(fontSize: 14),
|
titleSmall: TextStyle(fontSize: 14),
|
||||||
@ -229,27 +310,55 @@ class MyTheme {
|
|||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
splashFactory: isDesktop ? NoSplash.splashFactory : null,
|
splashFactory: isDesktop ? NoSplash.splashFactory : null,
|
||||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
|
||||||
style: OutlinedButton.styleFrom(
|
|
||||||
side: BorderSide(color: Colors.white38),
|
|
||||||
disabledForegroundColor: Colors.white70,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
textButtonTheme: isDesktop
|
textButtonTheme: isDesktop
|
||||||
? TextButtonThemeData(
|
? TextButtonThemeData(
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
splashFactory: NoSplash.splashFactory,
|
splashFactory: NoSplash.splashFactory,
|
||||||
disabledForegroundColor: Colors.white70,
|
disabledForegroundColor: Colors.white70,
|
||||||
))
|
foregroundColor: Colors.white70,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(18.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
: null,
|
: null,
|
||||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: MyTheme.accent,
|
||||||
disabledForegroundColor: Colors.white70,
|
disabledForegroundColor: Colors.white70,
|
||||||
disabledBackgroundColor: Colors.white10,
|
disabledBackgroundColor: Colors.white10,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
backgroundColor: Color(0xFF24252B),
|
||||||
|
side: BorderSide(color: Colors.white12, width: 0.5),
|
||||||
|
disabledForegroundColor: Colors.white70,
|
||||||
|
foregroundColor: Colors.white70,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
checkboxTheme: const CheckboxThemeData(
|
||||||
|
checkColor: MaterialStatePropertyAll(dark),
|
||||||
|
splashRadius: 0,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(5),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
listTileTheme: ListTileThemeData(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(5),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
checkboxTheme:
|
|
||||||
const CheckboxThemeData(checkColor: MaterialStatePropertyAll(dark)),
|
|
||||||
colorScheme: ColorScheme.fromSwatch(
|
colorScheme: ColorScheme.fromSwatch(
|
||||||
primarySwatch: Colors.blue,
|
primarySwatch: Colors.blue,
|
||||||
).copyWith(
|
).copyWith(
|
||||||
@ -480,7 +589,7 @@ class OverlayDialogManager {
|
|||||||
BackButtonInterceptor.removeByName(dialogTag);
|
BackButtonInterceptor.removeByName(dialogTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.entry = OverlayEntry(builder: (_) {
|
dialog.entry = OverlayEntry(builder: (context) {
|
||||||
bool innerClicked = false;
|
bool innerClicked = false;
|
||||||
return Listener(
|
return Listener(
|
||||||
onPointerUp: (_) {
|
onPointerUp: (_) {
|
||||||
@ -490,7 +599,9 @@ class OverlayDialogManager {
|
|||||||
innerClicked = false;
|
innerClicked = false;
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.black12,
|
color: Theme.of(context).brightness == Brightness.light
|
||||||
|
? Colors.black12
|
||||||
|
: Colors.black45,
|
||||||
child: StatefulBuilder(builder: (context, setState) {
|
child: StatefulBuilder(builder: (context, setState) {
|
||||||
return Listener(
|
return Listener(
|
||||||
onPointerUp: (_) => innerClicked = true,
|
onPointerUp: (_) => innerClicked = true,
|
||||||
@ -672,7 +783,7 @@ class CustomAlertDialog extends StatelessWidget {
|
|||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
if (!scopeNode.hasFocus) scopeNode.requestFocus();
|
if (!scopeNode.hasFocus) scopeNode.requestFocus();
|
||||||
});
|
});
|
||||||
const double padding = 16;
|
const double padding = 30;
|
||||||
bool tabTapped = false;
|
bool tabTapped = false;
|
||||||
return FocusScope(
|
return FocusScope(
|
||||||
node: scopeNode,
|
node: scopeNode,
|
||||||
@ -701,18 +812,19 @@ class CustomAlertDialog extends StatelessWidget {
|
|||||||
scrollable: true,
|
scrollable: true,
|
||||||
title: title,
|
title: title,
|
||||||
titlePadding: EdgeInsets.fromLTRB(padding, 24, padding, 0),
|
titlePadding: EdgeInsets.fromLTRB(padding, 24, padding, 0),
|
||||||
contentPadding: EdgeInsets.fromLTRB(contentPadding ?? padding, 25,
|
contentPadding: EdgeInsets.fromLTRB(
|
||||||
contentPadding ?? padding, actions is List ? 10 : padding),
|
contentPadding ?? padding,
|
||||||
|
25,
|
||||||
|
contentPadding ?? padding,
|
||||||
|
actions is List ? 10 : padding,
|
||||||
|
),
|
||||||
content: ConstrainedBox(
|
content: ConstrainedBox(
|
||||||
constraints: contentBoxConstraints,
|
constraints: contentBoxConstraints,
|
||||||
child: Theme(
|
child: content,
|
||||||
data: Theme.of(context).copyWith(
|
|
||||||
inputDecorationTheme: InputDecorationTheme(
|
|
||||||
isDense: true, contentPadding: EdgeInsets.all(15))),
|
|
||||||
child: content),
|
|
||||||
),
|
),
|
||||||
actions: actions,
|
actions: actions,
|
||||||
actionsPadding: EdgeInsets.fromLTRB(padding, 0, padding, padding),
|
actionsPadding: EdgeInsets.fromLTRB(padding, 0, padding, padding),
|
||||||
|
actionsAlignment: MainAxisAlignment.center,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1727,19 +1839,33 @@ class ServerConfig {
|
|||||||
Widget dialogButton(String text,
|
Widget dialogButton(String text,
|
||||||
{required VoidCallback? onPressed,
|
{required VoidCallback? onPressed,
|
||||||
bool isOutline = false,
|
bool isOutline = false,
|
||||||
|
Widget? icon,
|
||||||
TextStyle? style,
|
TextStyle? style,
|
||||||
ButtonStyle? buttonStyle}) {
|
ButtonStyle? buttonStyle}) {
|
||||||
if (isDesktop) {
|
if (isDesktop) {
|
||||||
if (isOutline) {
|
if (isOutline) {
|
||||||
return OutlinedButton(
|
return icon == null
|
||||||
|
? OutlinedButton(
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: Text(translate(text), style: style),
|
child: Text(translate(text), style: style),
|
||||||
|
)
|
||||||
|
: OutlinedButton.icon(
|
||||||
|
icon: icon,
|
||||||
|
onPressed: onPressed,
|
||||||
|
label: Text(translate(text), style: style),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return ElevatedButton(
|
return icon == null
|
||||||
|
? ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(elevation: 0).merge(buttonStyle),
|
style: ElevatedButton.styleFrom(elevation: 0).merge(buttonStyle),
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
child: Text(translate(text), style: style),
|
child: Text(translate(text), style: style),
|
||||||
|
)
|
||||||
|
: ElevatedButton.icon(
|
||||||
|
icon: icon,
|
||||||
|
style: ElevatedButton.styleFrom(elevation: 0).merge(buttonStyle),
|
||||||
|
onPressed: onPressed,
|
||||||
|
label: Text(translate(text), style: style),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1748,7 +1874,8 @@ Widget dialogButton(String text,
|
|||||||
child: Text(
|
child: Text(
|
||||||
translate(text),
|
translate(text),
|
||||||
style: style,
|
style: style,
|
||||||
));
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,19 +532,7 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
proc: () {
|
proc: () {
|
||||||
() async {
|
_delete(id, isLan, reloadFunc);
|
||||||
if (isLan) {
|
|
||||||
bind.mainRemoveDiscovered(id: id);
|
|
||||||
} else {
|
|
||||||
final favs = (await bind.mainGetFav()).toList();
|
|
||||||
if (favs.remove(id)) {
|
|
||||||
await bind.mainStoreFav(favs: favs);
|
|
||||||
}
|
|
||||||
await bind.mainRemovePeer(id: id);
|
|
||||||
}
|
|
||||||
removePreference(id);
|
|
||||||
await reloadFunc();
|
|
||||||
}();
|
|
||||||
},
|
},
|
||||||
padding: menuPadding,
|
padding: menuPadding,
|
||||||
dismissOnClicked: true,
|
dismissOnClicked: true,
|
||||||
@ -673,7 +661,13 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('Rename')),
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.edit_rounded, color: MyTheme.accent),
|
||||||
|
Text(translate('Rename')).paddingOnly(left: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
content: Column(
|
content: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -682,9 +676,7 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(labelText: translate('Name')),
|
||||||
border: OutlineInputBorder(),
|
|
||||||
labelText: translate('Name')),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -694,8 +686,17 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton("Cancel", onPressed: close, isOutline: true),
|
dialogButton(
|
||||||
dialogButton("OK", onPressed: submit),
|
"Cancel",
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: close,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"OK",
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: submit,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
onCancel: close,
|
onCancel: close,
|
||||||
@ -705,6 +706,58 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
|
|
||||||
@protected
|
@protected
|
||||||
void _update();
|
void _update();
|
||||||
|
|
||||||
|
void _delete(String id, bool isLan, Function reloadFunc) async {
|
||||||
|
gFFI.dialogManager.show(
|
||||||
|
(setState, close) {
|
||||||
|
submit() async {
|
||||||
|
if (isLan) {
|
||||||
|
bind.mainRemoveDiscovered(id: id);
|
||||||
|
} else {
|
||||||
|
final favs = (await bind.mainGetFav()).toList();
|
||||||
|
if (favs.remove(id)) {
|
||||||
|
await bind.mainStoreFav(favs: favs);
|
||||||
|
}
|
||||||
|
await bind.mainRemovePeer(id: id);
|
||||||
|
}
|
||||||
|
removePreference(id);
|
||||||
|
await reloadFunc();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CustomAlertDialog(
|
||||||
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.delete_rounded,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
Text(translate('Delete')).paddingOnly(
|
||||||
|
left: 10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
content: SizedBox.shrink(),
|
||||||
|
actions: [
|
||||||
|
dialogButton(
|
||||||
|
"Cancel",
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: close,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"OK",
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: submit,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onSubmit: submit,
|
||||||
|
onCancel: close,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RecentPeerCard extends BasePeerCard {
|
class RecentPeerCard extends BasePeerCard {
|
||||||
|
@ -300,14 +300,13 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
}
|
}
|
||||||
skipCount = index + 1;
|
skipCount = index + 1;
|
||||||
}
|
}
|
||||||
var searchResult = entries
|
var searchResult = entries.skip(skipCount).where(
|
||||||
.skip(skipCount)
|
(element) => element.name.toLowerCase().startsWith(buffer));
|
||||||
.where((element) => element.name.toLowerCase().startsWith(buffer));
|
|
||||||
if (searchResult.isEmpty) {
|
if (searchResult.isEmpty) {
|
||||||
// cannot find next, lets restart search from head
|
// cannot find next, lets restart search from head
|
||||||
debugPrint("restart search from head");
|
debugPrint("restart search from head");
|
||||||
searchResult =
|
searchResult = entries.where(
|
||||||
entries.where((element) => element.name.toLowerCase().startsWith(buffer));
|
(element) => element.name.toLowerCase().startsWith(buffer));
|
||||||
}
|
}
|
||||||
if (searchResult.isEmpty) {
|
if (searchResult.isEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -321,8 +320,8 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
onSearch: (buffer) {
|
onSearch: (buffer) {
|
||||||
debugPrint("searching for $buffer");
|
debugPrint("searching for $buffer");
|
||||||
final selectedEntries = getSelectedItems(isLocal);
|
final selectedEntries = getSelectedItems(isLocal);
|
||||||
final searchResult =
|
final searchResult = entries.where(
|
||||||
entries.where((element) => element.name.toLowerCase().startsWith(buffer));
|
(element) => element.name.toLowerCase().startsWith(buffer));
|
||||||
selectedEntries.clear();
|
selectedEntries.clear();
|
||||||
if (searchResult.isEmpty) {
|
if (searchResult.isEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -504,8 +503,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
debugPrint("entry is not valid: ${entry.path}");
|
debugPrint("entry is not valid: ${entry.path}");
|
||||||
}
|
}
|
||||||
final selectedEntries = getSelectedItems(isLocal);
|
final selectedEntries = getSelectedItems(isLocal);
|
||||||
final searchResult =
|
final searchResult = entries.where((element) => element == entry);
|
||||||
entries.where((element) => element == entry);
|
|
||||||
selectedEntries.clear();
|
selectedEntries.clear();
|
||||||
if (searchResult.isEmpty) {
|
if (searchResult.isEmpty) {
|
||||||
return;
|
return;
|
||||||
@ -976,14 +974,26 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
|
|
||||||
cancel() => close(false);
|
cancel() => close(false);
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate("Create Folder")),
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset("assets/folder_new.svg",
|
||||||
|
color: MyTheme.accent),
|
||||||
|
Text(
|
||||||
|
translate("Create Folder"),
|
||||||
|
).paddingOnly(
|
||||||
|
left: 10,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: translate(
|
labelText: translate(
|
||||||
"Please enter the folder name"),
|
"Please enter the folder name",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
controller: name,
|
controller: name,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -991,9 +1001,17 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton("Cancel",
|
dialogButton(
|
||||||
onPressed: cancel, isOutline: true),
|
"Cancel",
|
||||||
dialogButton("OK", onPressed: submit)
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: cancel,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"Ok",
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: submit,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
onCancel: cancel,
|
onCancel: cancel,
|
||||||
@ -1036,11 +1054,6 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
? MyTheme.accent80
|
? MyTheme.accent80
|
||||||
: MyTheme.accent,
|
: MyTheme.accent,
|
||||||
),
|
),
|
||||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
|
||||||
RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(18.0),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
onPressed: validItems(selectedItems)
|
onPressed: validItems(selectedItems)
|
||||||
? () {
|
? () {
|
||||||
@ -1467,10 +1480,8 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
axis: Axis.vertical,
|
axis: Axis.vertical,
|
||||||
onPointerMove: (dx) {
|
onPointerMove: (dx) {
|
||||||
nameColWidth.value += dx;
|
nameColWidth.value += dx;
|
||||||
nameColWidth.value = min(
|
nameColWidth.value = min(kDesktopFileTransferMaximumWidth,
|
||||||
kDesktopFileTransferMaximumWidth,
|
max(kDesktopFileTransferMinimumWidth, nameColWidth.value));
|
||||||
max(kDesktopFileTransferMinimumWidth,
|
|
||||||
nameColWidth.value));
|
|
||||||
},
|
},
|
||||||
padding: padding,
|
padding: padding,
|
||||||
),
|
),
|
||||||
|
@ -421,7 +421,8 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
SizedBox(width: _MenubarTheme.buttonHMargin)
|
SizedBox(width: _MenubarTheme.buttonHMargin)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
_buildDraggableShowHide(context),
|
_buildDraggableShowHide(context),
|
||||||
],
|
],
|
||||||
@ -434,7 +435,10 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
minimumSize: MaterialStatePropertyAll(Size(64, 36)),
|
minimumSize: MaterialStatePropertyAll(Size(64, 36)),
|
||||||
textStyle: MaterialStatePropertyAll(
|
textStyle: MaterialStatePropertyAll(
|
||||||
TextStyle(fontWeight: FontWeight.normal)))),
|
TextStyle(fontWeight: FontWeight.normal),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
dividerTheme: DividerThemeData(space: 4),
|
dividerTheme: DividerThemeData(space: 4),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -655,8 +659,16 @@ class _ControlMenu extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('OS Password')),
|
title: Row(
|
||||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.password_rounded, color: MyTheme.accent),
|
||||||
|
Text(translate('OS Password')).paddingOnly(left: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
PasswordWidget(controller: controller),
|
PasswordWidget(controller: controller),
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
contentPadding: const EdgeInsets.all(0),
|
contentPadding: const EdgeInsets.all(0),
|
||||||
@ -671,10 +683,20 @@ class _ControlMenu extends StatelessWidget {
|
|||||||
setState(() => autoLogin = v);
|
setState(() => autoLogin = v);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]),
|
],
|
||||||
|
),
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton('Cancel', onPressed: close, isOutline: true),
|
dialogButton(
|
||||||
dialogButton('OK', onPressed: submit),
|
"Cancel",
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: close,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"OK",
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: submit,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
onCancel: close,
|
onCancel: close,
|
||||||
|
@ -429,7 +429,7 @@ class ConnectionManager extends StatelessWidget {
|
|||||||
? ElevatedButton.icon(
|
? ElevatedButton.icon(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
MaterialStateProperty.all(Colors.red)),
|
MaterialStatePropertyAll(Colors.red)),
|
||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
bind.cmCloseConnection(connId: client.id);
|
bind.cmCloseConnection(connId: client.id);
|
||||||
|
@ -25,19 +25,26 @@ void showRestartRemoteDevice(
|
|||||||
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_rounded, color: Colors.redAccent, size: 28),
|
||||||
color: Colors.redAccent, size: 28),
|
Text(translate("Restart Remote Device")).paddingOnly(left: 10),
|
||||||
SizedBox(width: 10),
|
|
||||||
Text(translate("Restart Remote Device")),
|
|
||||||
]),
|
]),
|
||||||
content: Text(
|
content: Text(
|
||||||
"${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"),
|
"${translate('Are you sure you want to restart')} \n${pi.username}@${pi.hostname}($id) ?"),
|
||||||
|
actions: [
|
||||||
|
dialogButton(
|
||||||
|
"Cancel",
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: close,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"OK",
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: () => close(true),
|
||||||
|
),
|
||||||
|
],
|
||||||
onCancel: close,
|
onCancel: close,
|
||||||
onSubmit: () => close(true),
|
onSubmit: () => close(true),
|
||||||
actions: [
|
|
||||||
dialogButton("Cancel", onPressed: close, isOutline: true),
|
|
||||||
dialogButton("OK", onPressed: () => close(true)),
|
|
||||||
],
|
|
||||||
));
|
));
|
||||||
if (res == true) bind.sessionRestartRemoteDevice(id: id);
|
if (res == true) bind.sessionRestartRemoteDevice(id: id);
|
||||||
}
|
}
|
||||||
@ -62,7 +69,13 @@ void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('Set your own password')),
|
title: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.password_rounded, color: MyTheme.accent),
|
||||||
|
Text(translate('Set your own password')).paddingOnly(left: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
content: Form(
|
content: Form(
|
||||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
@ -112,11 +125,13 @@ void setPermanentPasswordDialog(OverlayDialogManager dialogManager) async {
|
|||||||
actions: [
|
actions: [
|
||||||
dialogButton(
|
dialogButton(
|
||||||
'Cancel',
|
'Cancel',
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
onPressed: close,
|
onPressed: close,
|
||||||
isOutline: true,
|
isOutline: true,
|
||||||
),
|
),
|
||||||
dialogButton(
|
dialogButton(
|
||||||
'OK',
|
'OK',
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
onPressed: (validateLength && validateSame) ? submit : null,
|
onPressed: (validateLength && validateSame) ? submit : null,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -178,7 +193,13 @@ void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Text(translate('Password Required')),
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.password_rounded, color: MyTheme.accent),
|
||||||
|
Text(translate('Password Required')).paddingOnly(left: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
PasswordWidget(controller: controller),
|
PasswordWidget(controller: controller),
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
@ -197,8 +218,17 @@ void enterPasswordDialog(String id, OverlayDialogManager dialogManager) async {
|
|||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton('Cancel', onPressed: cancel, isOutline: true),
|
dialogButton(
|
||||||
dialogButton('OK', onPressed: submit),
|
'Cancel',
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: cancel,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
'OK',
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: submit,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
onCancel: cancel,
|
onCancel: cancel,
|
||||||
|
@ -593,9 +593,12 @@ class FileModel extends ChangeNotifier {
|
|||||||
? "${translate("Are you sure you want to delete the file of this directory?")}\n"
|
? "${translate("Are you sure you want to delete the file of this directory?")}\n"
|
||||||
: "";
|
: "";
|
||||||
final count = entries.length > 1 ? "${i + 1}/${entries.length}" : "";
|
final count = entries.length > 1 ? "${i + 1}/${entries.length}" : "";
|
||||||
content = "$dirShow$count \n${entries[i].path}";
|
content = "$dirShow\n\n${entries[i].path}".trim();
|
||||||
final confirm =
|
final confirm = await showRemoveDialog(
|
||||||
await showRemoveDialog(title, content, item.isDirectory);
|
count.isEmpty ? title : "$title ($count)",
|
||||||
|
content,
|
||||||
|
item.isDirectory,
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
if (confirm == true) {
|
if (confirm == true) {
|
||||||
sendRemoveFile(entries[i].path, i, items.isLocal!);
|
sendRemoveFile(entries[i].path, i, items.isLocal!);
|
||||||
@ -636,22 +639,27 @@ class FileModel extends ChangeNotifier {
|
|||||||
submit() => close(true);
|
submit() => close(true);
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.warning, color: Colors.red),
|
const Icon(Icons.warning_rounded, color: Colors.red),
|
||||||
const SizedBox(width: 20),
|
Text(title).paddingOnly(
|
||||||
Text(title)
|
left: 10,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
contentBoxConstraints:
|
contentBoxConstraints:
|
||||||
BoxConstraints(minHeight: 100, minWidth: 400, maxWidth: 400),
|
BoxConstraints(minHeight: 100, minWidth: 400, maxWidth: 400),
|
||||||
content: Column(
|
content: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
children: [
|
||||||
Text(content),
|
Text(content),
|
||||||
const SizedBox(height: 5),
|
Text(
|
||||||
Text(translate("This is irreversible!"),
|
translate("This is irreversible!"),
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold)),
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
).paddingOnly(top: 20),
|
||||||
showCheckbox
|
showCheckbox
|
||||||
? CheckboxListTile(
|
? CheckboxListTile(
|
||||||
contentPadding: const EdgeInsets.all(0),
|
contentPadding: const EdgeInsets.all(0),
|
||||||
@ -667,10 +675,20 @@ class FileModel extends ChangeNotifier {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink()
|
: const SizedBox.shrink()
|
||||||
]),
|
],
|
||||||
|
),
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton("Cancel", onPressed: cancel, isOutline: true),
|
dialogButton(
|
||||||
dialogButton("OK", onPressed: submit),
|
"Cancel",
|
||||||
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: cancel,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"OK",
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: submit,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
onCancel: cancel,
|
onCancel: cancel,
|
||||||
@ -690,9 +708,10 @@ class FileModel extends ChangeNotifier {
|
|||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.warning, color: Colors.red),
|
const Icon(Icons.warning_rounded, color: Colors.red),
|
||||||
const SizedBox(width: 20),
|
Text(title).paddingOnly(
|
||||||
Text(title)
|
left: 10,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
contentBoxConstraints:
|
contentBoxConstraints:
|
||||||
@ -722,9 +741,23 @@ class FileModel extends ChangeNotifier {
|
|||||||
: const SizedBox.shrink()
|
: const SizedBox.shrink()
|
||||||
]),
|
]),
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton("Cancel", onPressed: cancel, isOutline: true),
|
dialogButton(
|
||||||
dialogButton("Skip", onPressed: () => close(null), isOutline: true),
|
"Cancel",
|
||||||
dialogButton("OK", onPressed: submit),
|
icon: Icon(Icons.close_rounded),
|
||||||
|
onPressed: cancel,
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"Skip",
|
||||||
|
icon: Icon(Icons.navigate_next_rounded),
|
||||||
|
onPressed: () => close(null),
|
||||||
|
isOutline: true,
|
||||||
|
),
|
||||||
|
dialogButton(
|
||||||
|
"OK",
|
||||||
|
icon: Icon(Icons.done_rounded),
|
||||||
|
onPressed: submit,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onSubmit: submit,
|
onSubmit: submit,
|
||||||
onCancel: cancel,
|
onCancel: cancel,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user