Merge branch 'master' into video_queue
This commit is contained in:
commit
bbaecb6b7f
7
.github/workflows/flutter-nightly.yml
vendored
7
.github/workflows/flutter-nightly.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
||||
# - { target: i686-pc-windows-msvc , os: windows-2019 }
|
||||
# - { target: x86_64-pc-windows-gnu , os: windows-2019 }
|
||||
- { target: x86_64-pc-windows-msvc, os: windows-2019 }
|
||||
# - { target: aarch64-pc-windows-msvc, os: windows-2019 }
|
||||
# - { target: aarch64-pc-windows-msvc, os: windows-2019, arch: aarch64 }
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
@ -264,11 +264,6 @@ jobs:
|
||||
os: macos-latest,
|
||||
extra-build-args: "",
|
||||
}
|
||||
- {
|
||||
target: aarch64-apple-darwin,
|
||||
os: macos-latest,
|
||||
extra-build-args: "",
|
||||
}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v3
|
||||
|
1022
Cargo.lock
generated
1022
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
19
Cargo.toml
19
Cargo.toml
@ -57,19 +57,18 @@ rpassword = "7.0"
|
||||
base64 = "0.21"
|
||||
num_cpus = "1.13"
|
||||
bytes = { version = "1.2", features = ["serde"] }
|
||||
default-net = "0.12.0"
|
||||
default-net = "0.14"
|
||||
wol-rs = "1.0"
|
||||
flutter_rust_bridge = { version = "1.61.1", optional = true }
|
||||
errno = "0.3"
|
||||
rdev = { git = "https://github.com/fufesou/rdev" }
|
||||
url = { version = "2.1", features = ["serde"] }
|
||||
dlopen = "0.1"
|
||||
hex = "0.4.3"
|
||||
crossbeam-queue = "0.3"
|
||||
|
||||
hex = "0.4"
|
||||
reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false }
|
||||
chrono = "0.4.23"
|
||||
cidr-utils = "0.5.9"
|
||||
chrono = "0.4"
|
||||
cidr-utils = "0.5"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies]
|
||||
cpal = "0.14"
|
||||
@ -95,8 +94,8 @@ winreg = "0.10"
|
||||
windows-service = "0.4"
|
||||
virtual_display = { path = "libs/virtual_display" }
|
||||
impersonate_system = { git = "https://github.com/21pages/impersonate-system" }
|
||||
shared_memory = "0.12.4"
|
||||
shutdown_hooks = "0.1.0"
|
||||
shared_memory = "0.12"
|
||||
shutdown_hooks = "0.1"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc = "0.2"
|
||||
@ -104,10 +103,10 @@ cocoa = "0.24"
|
||||
dispatch = "0.2"
|
||||
core-foundation = "0.9"
|
||||
core-graphics = "0.22"
|
||||
include_dir = "0.7.2"
|
||||
include_dir = "0.7"
|
||||
dark-light = "1.0"
|
||||
fruitbasket = "0.10.0"
|
||||
objc_id = "0.1.1"
|
||||
fruitbasket = "0.10"
|
||||
objc_id = "0.1"
|
||||
|
||||
[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies]
|
||||
tray-icon = "0.4"
|
||||
|
@ -186,6 +186,71 @@ class MyTheme {
|
||||
static const Color button = Color(0xFF2C8CFF);
|
||||
static const Color hoverBorder = Color(0xFF999999);
|
||||
|
||||
// ListTile
|
||||
static const ListTileThemeData listTileTheme = ListTileThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Checkbox
|
||||
static const CheckboxThemeData checkboxTheme = CheckboxThemeData(
|
||||
splashRadius: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(5),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// TextButton
|
||||
// Value is used to calculate "dialog.actionsPadding"
|
||||
static const double mobileTextButtonPaddingLR = 20;
|
||||
|
||||
// TextButton on mobile needs a fixed padding, otherwise small buttons
|
||||
// like "OK" has a larger left/right padding.
|
||||
static TextButtonThemeData mobileTextButtonTheme = TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(horizontal: mobileTextButtonPaddingLR),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Dialogs
|
||||
static const double dialogPadding = 24;
|
||||
|
||||
// padding bottom depends on content (some dialogs has no content)
|
||||
static EdgeInsets dialogTitlePadding({bool content = true}) {
|
||||
final double p = dialogPadding;
|
||||
|
||||
return EdgeInsets.fromLTRB(p, p, p, content ? 0 : p);
|
||||
}
|
||||
|
||||
// padding bottom depends on actions (mobile has dialogs without actions)
|
||||
static EdgeInsets dialogContentPadding({bool actions = true}) {
|
||||
final double p = dialogPadding;
|
||||
|
||||
return isDesktop
|
||||
? EdgeInsets.fromLTRB(p, p, p, actions ? (p - 4) : p)
|
||||
: EdgeInsets.fromLTRB(p, p, p, actions ? (p / 2) : p);
|
||||
}
|
||||
|
||||
static EdgeInsets dialogActionsPadding() {
|
||||
final double p = dialogPadding;
|
||||
|
||||
return isDesktop
|
||||
? EdgeInsets.fromLTRB(p, 0, p, (p - 4))
|
||||
: EdgeInsets.fromLTRB(p, 0, (p - mobileTextButtonPaddingLR), (p / 2));
|
||||
}
|
||||
|
||||
static EdgeInsets dialogButtonPadding = isDesktop
|
||||
? EdgeInsets.only(left: dialogPadding)
|
||||
: EdgeInsets.only(left: dialogPadding / 3);
|
||||
|
||||
static ThemeData lightTheme = ThemeData(
|
||||
brightness: Brightness.light,
|
||||
hoverColor: Color.fromARGB(255, 224, 224, 224),
|
||||
@ -236,7 +301,7 @@ class MyTheme {
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
: mobileTextButtonTheme,
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: MyTheme.accent,
|
||||
@ -254,21 +319,8 @@ class MyTheme {
|
||||
),
|
||||
),
|
||||
),
|
||||
checkboxTheme: const CheckboxThemeData(
|
||||
splashRadius: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(5),
|
||||
),
|
||||
),
|
||||
),
|
||||
listTileTheme: ListTileThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(5),
|
||||
),
|
||||
),
|
||||
),
|
||||
checkboxTheme: checkboxTheme,
|
||||
listTileTheme: listTileTheme,
|
||||
menuBarTheme: MenuBarThemeData(
|
||||
style:
|
||||
MenuStyle(backgroundColor: MaterialStatePropertyAll(Colors.white))),
|
||||
@ -334,7 +386,7 @@ class MyTheme {
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
: mobileTextButtonTheme,
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: MyTheme.accent,
|
||||
@ -357,21 +409,8 @@ class MyTheme {
|
||||
),
|
||||
),
|
||||
),
|
||||
checkboxTheme: const CheckboxThemeData(
|
||||
splashRadius: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(5),
|
||||
),
|
||||
),
|
||||
),
|
||||
listTileTheme: ListTileThemeData(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(5),
|
||||
),
|
||||
),
|
||||
),
|
||||
checkboxTheme: checkboxTheme,
|
||||
listTileTheme: listTileTheme,
|
||||
menuBarTheme: MenuBarThemeData(
|
||||
style: MenuStyle(
|
||||
backgroundColor: MaterialStatePropertyAll(Color(0xFF121212)))),
|
||||
@ -771,6 +810,10 @@ void showToast(String text, {Duration timeout = const Duration(seconds: 2)}) {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - Remove argument "contentPadding", no need for it, all should look the same.
|
||||
// - Remove "required" for argument "content". See simple confirm dialog "delete peer", only title and actions are used. No need to "content: SizedBox.shrink()".
|
||||
// - Make dead code alive, transform arguments "onSubmit" and "onCancel" into correspondenting buttons "ConfirmOkButton", "CancelButton".
|
||||
class CustomAlertDialog extends StatelessWidget {
|
||||
const CustomAlertDialog(
|
||||
{Key? key,
|
||||
@ -798,8 +841,8 @@ class CustomAlertDialog extends StatelessWidget {
|
||||
Future.delayed(Duration.zero, () {
|
||||
if (!scopeNode.hasFocus) scopeNode.requestFocus();
|
||||
});
|
||||
const double padding = 30;
|
||||
bool tabTapped = false;
|
||||
|
||||
return FocusScope(
|
||||
node: scopeNode,
|
||||
autofocus: true,
|
||||
@ -824,22 +867,18 @@ class CustomAlertDialog extends StatelessWidget {
|
||||
return KeyEventResult.ignored;
|
||||
},
|
||||
child: AlertDialog(
|
||||
scrollable: true,
|
||||
title: title,
|
||||
titlePadding: EdgeInsets.fromLTRB(padding, 24, padding, 0),
|
||||
contentPadding: EdgeInsets.fromLTRB(
|
||||
contentPadding ?? padding,
|
||||
25,
|
||||
contentPadding ?? padding,
|
||||
actions is List ? 10 : padding,
|
||||
),
|
||||
content: ConstrainedBox(
|
||||
constraints: contentBoxConstraints,
|
||||
child: content,
|
||||
),
|
||||
actions: actions,
|
||||
actionsPadding: EdgeInsets.fromLTRB(padding, 0, padding, padding),
|
||||
),
|
||||
scrollable: true,
|
||||
title: title,
|
||||
content: ConstrainedBox(
|
||||
constraints: contentBoxConstraints,
|
||||
child: content,
|
||||
),
|
||||
actions: actions,
|
||||
titlePadding: MyTheme.dialogTitlePadding(content: content != null),
|
||||
contentPadding:
|
||||
MyTheme.dialogContentPadding(actions: actions is List),
|
||||
actionsPadding: MyTheme.dialogActionsPadding(),
|
||||
buttonPadding: MyTheme.dialogButtonPadding),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1115,25 +1154,32 @@ class AndroidPermissionManager {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO move this to mobile/widgets.
|
||||
// Used only for mobile, pages remote, settings, dialog
|
||||
// TODO remove argument contentPadding, it’s not used, getToggle() has not
|
||||
RadioListTile<T> getRadio<T>(
|
||||
String name, T toValue, T curValue, void Function(T?) onChange,
|
||||
{EdgeInsetsGeometry? contentPadding}) {
|
||||
return RadioListTile<T>(
|
||||
contentPadding: contentPadding,
|
||||
contentPadding: contentPadding ?? EdgeInsets.zero,
|
||||
visualDensity: VisualDensity.compact,
|
||||
controlAffinity: ListTileControlAffinity.trailing,
|
||||
title: Text(translate(name)),
|
||||
value: toValue,
|
||||
groupValue: curValue,
|
||||
onChanged: onChange,
|
||||
dense: true,
|
||||
);
|
||||
}
|
||||
|
||||
// TODO move this to mobile/widgets.
|
||||
// Used only for mobile, pages remote, settings, dialog
|
||||
CheckboxListTile getToggle(
|
||||
String id, void Function(void Function()) setState, option, name,
|
||||
{FFI? ffi}) {
|
||||
final opt = bind.sessionGetToggleOptionSync(id: id, arg: option);
|
||||
return CheckboxListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
visualDensity: VisualDensity.compact,
|
||||
value: opt,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
@ -1143,7 +1189,6 @@ CheckboxListTile getToggle(
|
||||
(ffi ?? gFFI).qualityMonitorModel.checkShowQualityMonitor(id);
|
||||
}
|
||||
},
|
||||
dense: true,
|
||||
title: Text(translate(name)));
|
||||
}
|
||||
|
||||
|
@ -802,7 +802,7 @@ class _FileManagerViewState extends State<FileManagerView> {
|
||||
switchType: SwitchType.scheckbox,
|
||||
text: translate("Show Hidden Files"),
|
||||
getter: () async {
|
||||
return controller.options.value.isWindows;
|
||||
return controller.options.value.showHidden;
|
||||
},
|
||||
setter: (bool v) async {
|
||||
controller.toggleShowHidden();
|
||||
|
@ -696,10 +696,8 @@ class _RemotePageState extends State<RemotePage> {
|
||||
// return CustomAlertDialog(
|
||||
// title: Text(translate('Physical Keyboard Input Mode')),
|
||||
// content: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
// getRadio('Legacy mode', 'legacy', current, setMode,
|
||||
// contentPadding: EdgeInsets.zero),
|
||||
// getRadio('Map mode', 'map', current, setMode,
|
||||
// contentPadding: EdgeInsets.zero),
|
||||
// getRadio('Legacy mode', 'legacy', current, setMode),
|
||||
// getRadio('Map mode', 'map', current, setMode),
|
||||
// ]));
|
||||
// }, clickMaskDismiss: true);
|
||||
// }
|
||||
@ -1069,7 +1067,6 @@ void showOptions(
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: displays + radios + toggles + more),
|
||||
contentPadding: 0,
|
||||
);
|
||||
}, clickMaskDismiss: true, backDismiss: true);
|
||||
}
|
||||
|
@ -502,19 +502,18 @@ void showLanguageSettings(OverlayDialogManager dialogManager) async {
|
||||
}
|
||||
|
||||
return CustomAlertDialog(
|
||||
title: SizedBox.shrink(),
|
||||
content: Column(
|
||||
children: [
|
||||
getRadio('Default', '', lang, setLang),
|
||||
Divider(color: MyTheme.border),
|
||||
] +
|
||||
langs.map((e) {
|
||||
final key = e[0] as String;
|
||||
final name = e[1] as String;
|
||||
return getRadio(name, key, lang, setLang);
|
||||
}).toList(),
|
||||
),
|
||||
actions: []);
|
||||
content: Column(
|
||||
children: [
|
||||
getRadio('Default', '', lang, setLang),
|
||||
Divider(color: MyTheme.border),
|
||||
] +
|
||||
langs.map((e) {
|
||||
final key = e[0] as String;
|
||||
final name = e[1] as String;
|
||||
return getRadio(name, key, lang, setLang);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}, backDismiss: true, clickMaskDismiss: true);
|
||||
} catch (e) {
|
||||
//
|
||||
@ -536,14 +535,12 @@ void showThemeSettings(OverlayDialogManager dialogManager) async {
|
||||
}
|
||||
|
||||
return CustomAlertDialog(
|
||||
title: SizedBox.shrink(),
|
||||
contentPadding: 10,
|
||||
content: Column(children: [
|
||||
getRadio('Light', ThemeMode.light, themeMode, setTheme),
|
||||
getRadio('Dark', ThemeMode.dark, themeMode, setTheme),
|
||||
getRadio('Follow System', ThemeMode.system, themeMode, setTheme)
|
||||
]),
|
||||
actions: []);
|
||||
content: Column(children: [
|
||||
getRadio('Light', ThemeMode.light, themeMode, setTheme),
|
||||
getRadio('Dark', ThemeMode.dark, themeMode, setTheme),
|
||||
getRadio('Follow System', ThemeMode.system, themeMode, setTheme)
|
||||
]),
|
||||
);
|
||||
}, backDismiss: true, clickMaskDismiss: true);
|
||||
}
|
||||
|
||||
|
@ -128,12 +128,19 @@ void setTemporaryPasswordLengthDialog(
|
||||
|
||||
return CustomAlertDialog(
|
||||
title: Text(translate("Set one-time password length")),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children:
|
||||
lengths.map((e) => getRadio(e, e, length, setLength)).toList()),
|
||||
actions: [],
|
||||
contentPadding: 14,
|
||||
content: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: lengths
|
||||
.map(
|
||||
(value) => Row(
|
||||
children: [
|
||||
Text(value),
|
||||
Radio(
|
||||
value: value, groupValue: length, onChanged: setLength),
|
||||
],
|
||||
),
|
||||
)
|
||||
.toList()),
|
||||
);
|
||||
}, backDismiss: true, clickMaskDismiss: true);
|
||||
}
|
||||
|
BIN
res/icon.ico
BIN
res/icon.ico
Binary file not shown.
Before Width: | Height: | Size: 48 B After Width: | Height: | Size: 1.9 KiB |
@ -1193,7 +1193,9 @@ fn is_function_key(ck: &EnumOrUnknown<ControlKey>) -> bool {
|
||||
});
|
||||
res = true;
|
||||
} else if ck.value() == ControlKey::LockScreen.value() {
|
||||
lock_screen_2();
|
||||
std::thread::spawn(|| {
|
||||
lock_screen_2();
|
||||
});
|
||||
res = true;
|
||||
}
|
||||
return res;
|
||||
|
Loading…
x
Reference in New Issue
Block a user