-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SecurityPage: add security pages (#269)
- Loading branch information
1 parent
1eb7d4e
commit 0a45e3d
Showing
15 changed files
with
686 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:dbus/dbus.dart'; | ||
|
||
const kHouseKeepingInterface = 'org.gnome.SettingsDaemon.Housekeeping'; | ||
const kHouseKeepingPath = '/org/gnome/SettingsDaemon/Housekeeping'; | ||
const kEmptyTrashMethodName = 'EmptyTrash'; | ||
const kRemoveTempFiles = 'RemoveTempFiles'; | ||
|
||
class HouseKeepingService { | ||
final DBusRemoteObject _object; | ||
|
||
HouseKeepingService() : _object = _createObject(); | ||
|
||
static DBusRemoteObject _createObject() { | ||
return DBusRemoteObject( | ||
DBusClient.session(), | ||
name: kHouseKeepingInterface, | ||
path: DBusObjectPath(kHouseKeepingPath), | ||
); | ||
} | ||
|
||
Future<void> dispose() async { | ||
await _object.client.close(); | ||
} | ||
|
||
void emptyTrash() => _object.emptyTrash(); | ||
|
||
void removeTempFiles() => _object.removeTempFiles(); | ||
} | ||
|
||
extension _HouseKeepingObject on DBusRemoteObject { | ||
Future<DBusMethodSuccessResponse> emptyTrash() { | ||
return callMethod(kHouseKeepingInterface, kEmptyTrashMethodName, []); | ||
} | ||
|
||
Future<DBusMethodSuccessResponse> removeTempFiles() { | ||
return callMethod(kHouseKeepingInterface, kRemoveTempFiles, []); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import 'package:nm/nm.dart'; | ||
import 'package:safe_change_notifier/safe_change_notifier.dart'; | ||
|
||
class ConnectivityModel extends SafeChangeNotifier { | ||
final NetworkManagerClient _client; | ||
|
||
Future<void> init() { | ||
final network = _client.connect(); | ||
return Future.wait([network]); | ||
} | ||
|
||
ConnectivityModel(NetworkManagerClient client) : _client = client; | ||
|
||
bool? get checkConnectiviy => _client.connectivityCheckEnabled; | ||
set checkConnectiviy(bool? value) { | ||
if (value == null) return; | ||
_client | ||
.setConnectivityCheckEnabled(value) | ||
.then((value) => notifyListeners()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:nm/nm.dart'; | ||
import 'package:provider/provider.dart'; | ||
import 'package:settings/constants.dart'; | ||
import 'package:settings/view/pages/privacy/connectivity_model.dart'; | ||
import 'package:yaru_widgets/yaru_widgets.dart'; | ||
|
||
class ConnectivityPage extends StatefulWidget { | ||
const ConnectivityPage({Key? key}) : super(key: key); | ||
|
||
static Widget create(BuildContext context) => ChangeNotifierProvider( | ||
create: (_) => ConnectivityModel(context.read<NetworkManagerClient>()), | ||
child: const ConnectivityPage()); | ||
|
||
@override | ||
State<ConnectivityPage> createState() => _ConnectivityPageState(); | ||
} | ||
|
||
class _ConnectivityPageState extends State<ConnectivityPage> { | ||
@override | ||
void initState() { | ||
final model = context.read<ConnectivityModel>(); | ||
model.init(); | ||
super.initState(); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final model = context.watch<ConnectivityModel>(); | ||
return YaruPage(children: [ | ||
YaruSwitchRow( | ||
width: kDefaultWidth, | ||
enabled: model.checkConnectiviy != null, | ||
trailingWidget: const Text('Check Connectivity'), | ||
value: model.checkConnectiviy, | ||
onChanged: (v) => model.checkConnectiviy = v, | ||
) | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:provider/provider.dart'; | ||
import 'package:settings/constants.dart'; | ||
import 'package:settings/services/house_keeping_service.dart'; | ||
import 'package:settings/services/settings_service.dart'; | ||
import 'package:settings/view/pages/privacy/privacy_model.dart'; | ||
import 'package:yaru_icons/yaru_icons.dart'; | ||
import 'package:yaru_widgets/yaru_widgets.dart'; | ||
|
||
class HouseKeepingPage extends StatelessWidget { | ||
const HouseKeepingPage({Key? key}) : super(key: key); | ||
|
||
static Widget create(BuildContext context) => ChangeNotifierProvider( | ||
create: (_) => PrivacyModel(context.read<SettingsService>(), | ||
context.read<HouseKeepingService>()), | ||
child: const HouseKeepingPage(), | ||
); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final model = context.watch<PrivacyModel>(); | ||
return YaruPage(children: [ | ||
YaruSection( | ||
width: kDefaultWidth, | ||
headline: 'Recent Files History', | ||
children: [ | ||
YaruSwitchRow( | ||
enabled: model.rememberRecentFiles != null, | ||
trailingWidget: const Text('Remember recent files'), | ||
value: model.rememberRecentFiles, | ||
onChanged: (value) => model.rememberRecentFiles = value, | ||
), | ||
if (model.rememberRecentFiles != null && | ||
model.rememberRecentFiles == true) | ||
YaruSwitchRow( | ||
enabled: model.recentFilesMaxAge != null, | ||
trailingWidget: const Text('Remember recent files forever'), | ||
value: model.recentFilesMaxAge?.toDouble() == -1, | ||
onChanged: (value) { | ||
final intValue = value ? -1 : 1; | ||
return model.recentFilesMaxAge = intValue; | ||
}), | ||
if (model.recentFilesMaxAge != null && | ||
model.recentFilesMaxAge?.toDouble() != -1 && | ||
model.rememberRecentFiles != null && | ||
model.rememberRecentFiles == true) | ||
YaruSliderRow( | ||
enabled: model.recentFilesMaxAge != null, | ||
actionLabel: 'Days recorded', | ||
value: model.recentFilesMaxAge?.toDouble() == -1 | ||
? -1 | ||
: model.recentFilesMaxAge?.toDouble(), | ||
min: -1, | ||
max: 30, | ||
onChanged: (value) => model.recentFilesMaxAge = value.toInt()) | ||
], | ||
), | ||
YaruSection( | ||
width: kDefaultWidth, | ||
headline: 'Trash & Temp Files', | ||
children: [ | ||
YaruSwitchRow( | ||
enabled: model.removeOldTempFiles != null, | ||
trailingWidget: const Text('Auto-remove old temp files'), | ||
value: model.removeOldTempFiles, | ||
onChanged: (value) => model.removeOldTempFiles = value, | ||
), | ||
YaruSwitchRow( | ||
enabled: model.removeOldTrashFiles != null, | ||
trailingWidget: const Text('Auto-remove old trash files'), | ||
value: model.removeOldTrashFiles, | ||
onChanged: (value) => model.removeOldTrashFiles = value, | ||
), | ||
if (model.oldFilesAge != null && model.oldFilesAge?.toDouble() != -1) | ||
YaruSliderRow( | ||
enabled: model.oldFilesAge != null, | ||
actionLabel: 'Days until auto-delete', | ||
value: model.oldFilesAge?.toDouble() == -1 | ||
? -1 | ||
: model.oldFilesAge?.toDouble(), | ||
min: 0, | ||
max: 30, | ||
onChanged: (value) => model.oldFilesAge = value.toInt()), | ||
YaruRow( | ||
trailingWidget: const Text('Clean the house'), | ||
actionWidget: Row( | ||
children: [ | ||
OutlinedButton( | ||
onPressed: () => showDialog( | ||
context: context, | ||
builder: (context) => _ConfirmationDialog( | ||
title: 'Empty trash', | ||
iconData: YaruIcons.trash_full, | ||
onConfirm: () { | ||
model.emptyTrash(); | ||
Navigator.of(context).pop(); | ||
}, | ||
), | ||
), | ||
child: Text('Empty Trash', | ||
style: | ||
TextStyle(color: Theme.of(context).errorColor))), | ||
const SizedBox( | ||
width: 10, | ||
), | ||
OutlinedButton( | ||
onPressed: () => showDialog( | ||
context: context, | ||
builder: (context) => _ConfirmationDialog( | ||
title: 'Remove Temp Files', | ||
iconData: YaruIcons.document, | ||
onConfirm: () { | ||
model.removeTempFiles(); | ||
Navigator.of(context).pop(); | ||
}, | ||
), | ||
), | ||
child: Text('Remove Temp Files', | ||
style: | ||
TextStyle(color: Theme.of(context).errorColor))), | ||
], | ||
), | ||
enabled: true) | ||
], | ||
), | ||
]); | ||
} | ||
} | ||
|
||
class _ConfirmationDialog extends StatefulWidget { | ||
const _ConfirmationDialog({ | ||
Key? key, | ||
this.onConfirm, | ||
required this.iconData, | ||
this.title, | ||
}) : super(key: key); | ||
|
||
final Function()? onConfirm; | ||
final IconData iconData; | ||
final String? title; | ||
|
||
@override | ||
State<_ConfirmationDialog> createState() => _ConfirmationDialogState(); | ||
} | ||
|
||
class _ConfirmationDialogState extends State<_ConfirmationDialog> | ||
with SingleTickerProviderStateMixin { | ||
late AnimationController controller; | ||
late Animation sizeAnimation; | ||
late Animation colorAnimation; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
controller = | ||
AnimationController(vsync: this, duration: const Duration(seconds: 2)); | ||
sizeAnimation = Tween<double>(begin: 100.0, end: 400.0).animate(controller); | ||
colorAnimation = | ||
ColorTween(begin: Colors.red, end: Colors.red.withOpacity(0.2)) | ||
.animate(controller); | ||
controller.addListener(() { | ||
setState(() {}); | ||
}); | ||
controller.repeat(); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
controller.stop(); | ||
super.dispose(); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return AlertDialog( | ||
titlePadding: EdgeInsets.zero, | ||
title: YaruDialogTitle( | ||
title: widget.title, | ||
), | ||
content: Icon( | ||
widget.iconData, | ||
size: 100, | ||
color: colorAnimation.value, | ||
), | ||
contentPadding: const EdgeInsets.only(top: 20, bottom: 50), | ||
actions: [ | ||
OutlinedButton( | ||
onPressed: () => Navigator.of(context).pop(), | ||
child: const Text('Cancel')), | ||
OutlinedButton( | ||
onPressed: widget.onConfirm, | ||
child: Text( | ||
'Confirm', | ||
style: TextStyle(color: Theme.of(context).errorColor), | ||
)) | ||
], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import 'package:safe_change_notifier/safe_change_notifier.dart'; | ||
import 'package:settings/schemas/schemas.dart'; | ||
import 'package:settings/services/settings_service.dart'; | ||
|
||
const _enabledKey = 'enabled'; | ||
|
||
class LocationModel extends SafeChangeNotifier { | ||
final Settings? _locationSettings; | ||
|
||
LocationModel(SettingsService service) | ||
: _locationSettings = service.lookup(schemaLocation) { | ||
_locationSettings?.addListener(notifyListeners); | ||
} | ||
|
||
bool? get enabled => _locationSettings?.getValue(_enabledKey); | ||
set enabled(bool? value) { | ||
if (value == null) return; | ||
_locationSettings?.setValue(_enabledKey, value); | ||
notifyListeners(); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
_locationSettings?.removeListener(notifyListeners); | ||
super.dispose(); | ||
} | ||
} |
Oops, something went wrong.