feat: option, enable-privacy-mode & enable-perm-change-in-accept-window (#14875)

* feat: option, privacy mode

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): update libs/hbb_common

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): turn off on disable privacy mode

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): better check if supported

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(option): enable perm change in accept window

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2026-05-02 00:44:22 +08:00
committed by GitHub
parent d4a1430c27
commit 383a5c3478
70 changed files with 437 additions and 57 deletions

View File

@@ -1183,7 +1183,8 @@ void showOptions(
List<TToggleMenu> privacyModeList = [];
// privacy mode
final privacyModeState = PrivacyModeState.find(id);
if (gFFI.ffiModel.keyboard && gFFI.ffiModel.pi.features.privacyMode) {
if ((gFFI.ffiModel.pi.features.privacyMode && gFFI.ffiModel.keyboard) ||
privacyModeState.isNotEmpty) {
privacyModeList = toolbarPrivacyMode(privacyModeState, context, id, gFFI);
if (privacyModeList.length == 1) {
displayToggles.add(privacyModeList[0]);

View File

@@ -583,9 +583,16 @@ class _PermissionCheckerState extends State<PermissionChecker> {
Widget build(BuildContext context) {
final serverModel = Provider.of<ServerModel>(context);
final hasAudioPermission = androidVersion >= 30;
final hideStopService =
isAndroid &&
bind.mainGetBuildinOption(key: kOptionHideStopService) == 'Y';
final hideStopService = isAndroid &&
bind.mainGetBuildinOption(key: kOptionHideStopService) == 'Y';
final allowPermChangeInAcceptWindow = option2bool(
kOptionEnablePermChangeInAcceptWindow,
bind.mainGetBuildinOption(
key: kOptionEnablePermChangeInAcceptWindow,
));
final permissionChangeLocked = isAndroid &&
serverModel.clients.any((c) => !c.disconnected) &&
!allowPermChangeInAcceptWindow;
return PaddingCard(
title: translate("Permissions"),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
@@ -608,13 +615,21 @@ class _PermissionCheckerState extends State<PermissionChecker> {
bind.mainGetLocalOption(key: "show-scam-warning") != "N"
? () => showScamWarning(context, serverModel)
: serverModel.toggleService),
PermissionRow(translate("Input Control"), serverModel.inputOk,
serverModel.toggleInput),
PermissionRow(translate("Transfer file"), serverModel.fileOk,
serverModel.toggleFile),
PermissionRow(
translate("Input Control"),
serverModel.inputOk,
serverModel.toggleInput,
),
PermissionRow(
translate("Transfer file"),
serverModel.fileOk,
serverModel.toggleFile,
enabled: !permissionChangeLocked,
),
hasAudioPermission
? PermissionRow(translate("Audio Capture"), serverModel.audioOk,
serverModel.toggleAudio)
serverModel.toggleAudio,
enabled: !permissionChangeLocked)
: Row(children: [
Icon(Icons.info_outline).marginOnly(right: 15),
Expanded(
@@ -623,19 +638,25 @@ class _PermissionCheckerState extends State<PermissionChecker> {
style: const TextStyle(color: MyTheme.darkGray),
))
]),
PermissionRow(translate("Enable clipboard"), serverModel.clipboardOk,
serverModel.toggleClipboard),
PermissionRow(
translate("Enable clipboard"),
serverModel.clipboardOk,
serverModel.toggleClipboard,
enabled: !permissionChangeLocked,
),
]));
}
}
class PermissionRow extends StatelessWidget {
const PermissionRow(this.name, this.isOk, this.onPressed, {Key? key})
const PermissionRow(this.name, this.isOk, this.onPressed,
{Key? key, this.enabled = true})
: super(key: key);
final String name;
final bool isOk;
final VoidCallback onPressed;
final bool enabled;
@override
Widget build(BuildContext context) {
@@ -644,9 +665,11 @@ class PermissionRow extends StatelessWidget {
contentPadding: EdgeInsets.all(0),
title: Text(name),
value: isOk,
onChanged: (bool value) {
onPressed();
});
onChanged: enabled
? (bool value) {
onPressed();
}
: null);
}
}