Line data Source code
1 : import 'dart:io';
2 :
3 : import 'package:flutter/material.dart';
4 : import 'package:flutter/services.dart';
5 : import 'package:provider/provider.dart';
6 : import 'package:flutter_gen/gen_l10n/app_localizations.dart';
7 :
8 : import '../cwtch_icons_icons.dart';
9 : import '../settings.dart';
10 : import '../themes/opaque.dart';
11 : import 'globalsettingsview.dart';
12 :
13 : class GlobalSettingsBehaviourView extends StatefulWidget {
14 0 : @override
15 0 : _GlobalSettingsBehaviourViewState createState() => _GlobalSettingsBehaviourViewState();
16 : }
17 :
18 : class _GlobalSettingsBehaviourViewState extends State<GlobalSettingsBehaviourView> {
19 : static const androidSettingsChannel = const MethodChannel('androidSettings');
20 : static const androidSettingsChangeChannel = const MethodChannel('androidSettingsChanged');
21 :
22 : ScrollController settingsListScrollController = ScrollController();
23 : bool powerExempt = false;
24 :
25 0 : @override
26 : void initState() {
27 0 : super.initState();
28 0 : androidSettingsChangeChannel.setMethodCallHandler(handleSettingsChanged);
29 :
30 0 : if (Platform.isAndroid) {
31 0 : isBatteryExempt().then((value) => setState(() {
32 0 : powerExempt = value;
33 : }));
34 : } else {
35 0 : powerExempt = false;
36 : }
37 : }
38 :
39 : // Handler on method channel for MainActivity/onActivityResult to report the user choice when we ask for power exemption
40 0 : Future<void> handleSettingsChanged(MethodCall call) async {
41 0 : if (call.method == "powerExemptionChange") {
42 0 : if (call.arguments) {
43 0 : setState(() {
44 0 : powerExempt = true;
45 : });
46 : }
47 : }
48 : }
49 : //* Android Only Requests
50 :
51 0 : Future<bool> isBatteryExempt() async {
52 0 : return await androidSettingsChannel.invokeMethod('isBatteryExempt', {}) ?? false;
53 : }
54 :
55 0 : Future<void> requestBatteryExemption() async {
56 0 : await androidSettingsChannel.invokeMethod('requestBatteryExemption', {});
57 0 : return Future.value();
58 : }
59 :
60 : //* End Android Only Requests
61 :
62 0 : Widget build(BuildContext context) {
63 0 : return Consumer<Settings>(builder: (ccontext, settings, child) {
64 0 : return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
65 0 : return Scrollbar(
66 0 : key: Key("BehaviourSettingsView"),
67 : trackVisibility: true,
68 0 : controller: settingsListScrollController,
69 0 : child: SingleChildScrollView(
70 : clipBehavior: Clip.antiAlias,
71 0 : controller: settingsListScrollController,
72 0 : child: ConstrainedBox(
73 0 : constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight, maxWidth: viewportConstraints.maxWidth),
74 0 : child: Container(
75 0 : color: settings.theme.backgroundPaneColor,
76 0 : child: Column(children: [
77 0 : Visibility(
78 0 : visible: Platform.isAndroid,
79 0 : child: SwitchListTile(
80 0 : title: Text(AppLocalizations.of(context)!.settingAndroidPowerExemption),
81 0 : subtitle: Text(AppLocalizations.of(context)!.settingAndroidPowerExemptionDescription),
82 0 : value: powerExempt,
83 0 : onChanged: (bool value) {
84 : if (value) {
85 0 : requestBatteryExemption();
86 : } else {
87 : // We can't ask for it to be turned off, show an informational popup
88 0 : showBatteryDialog(context);
89 : }
90 : },
91 0 : activeTrackColor: settings.theme.defaultButtonColor,
92 0 : inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
93 0 : secondary: Icon(Icons.power, color: settings.current().mainTextColor),
94 : ),
95 : ),
96 0 : ListTile(
97 0 : title: Text(AppLocalizations.of(context)!.notificationPolicySettingLabel),
98 0 : subtitle: Text(AppLocalizations.of(context)!.notificationPolicySettingDescription),
99 0 : trailing: Container(
100 0 : width: MediaQuery.of(context).size.width / 4,
101 0 : child: DropdownButton(
102 : isExpanded: true,
103 0 : value: settings.notificationPolicy,
104 0 : onChanged: (NotificationPolicy? newValue) {
105 0 : settings.notificationPolicy = newValue!;
106 0 : saveSettings(context);
107 : },
108 0 : items: NotificationPolicy.values.map<DropdownMenuItem<NotificationPolicy>>((NotificationPolicy value) {
109 0 : return DropdownMenuItem<NotificationPolicy>(
110 : value: value,
111 0 : child: Text(Settings.notificationPolicyToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
112 : );
113 0 : }).toList())),
114 0 : leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
115 : ),
116 0 : ListTile(
117 0 : title: Text(AppLocalizations.of(context)!.notificationContentSettingLabel),
118 0 : subtitle: Text(AppLocalizations.of(context)!.notificationContentSettingDescription),
119 0 : trailing: Container(
120 0 : width: MediaQuery.of(context).size.width / 4,
121 0 : child: DropdownButton(
122 : isExpanded: true,
123 0 : value: settings.notificationContent,
124 0 : onChanged: (NotificationContent? newValue) {
125 0 : settings.notificationContent = newValue!;
126 0 : saveSettings(context);
127 : },
128 0 : items: NotificationContent.values.map<DropdownMenuItem<NotificationContent>>((NotificationContent value) {
129 0 : return DropdownMenuItem<NotificationContent>(
130 : value: value,
131 : child:
132 0 : Text(Settings.notificationContentToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)),
133 : );
134 0 : }).toList())),
135 0 : leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
136 : ),
137 0 : SwitchListTile(
138 0 : title: Text(AppLocalizations.of(context)!.blockUnknownLabel),
139 0 : subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections),
140 0 : value: settings.blockUnknownConnections,
141 0 : onChanged: (bool value) {
142 : if (value) {
143 0 : settings.forbidUnknownConnections();
144 : } else {
145 0 : settings.allowUnknownConnections();
146 : }
147 :
148 : // Save Settings...
149 0 : saveSettings(context);
150 : },
151 0 : activeTrackColor: settings.theme.defaultButtonColor,
152 0 : inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
153 0 : secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor),
154 : ),
155 0 : SwitchListTile(
156 0 : title: Text(AppLocalizations.of(context)!.defaultPreserveHistorySetting),
157 0 : subtitle: Text(AppLocalizations.of(context)!.preserveHistorySettingDescription),
158 0 : value: settings.preserveHistoryByDefault,
159 0 : onChanged: (bool value) {
160 : if (value) {
161 0 : settings.setPreserveHistoryDefault();
162 : } else {
163 0 : settings.setDeleteHistoryDefault();
164 : }
165 :
166 : // Save Settings...
167 0 : saveSettings(context);
168 : },
169 0 : activeTrackColor: settings.theme.defaultButtonColor,
170 0 : inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
171 0 : secondary: Icon(CwtchIcons.peer_history, color: settings.current().mainTextColor),
172 : ),
173 : ])))));
174 : });
175 : });
176 : }
177 :
178 0 : showBatteryDialog(BuildContext context) {
179 0 : Widget okButton = ElevatedButton(
180 0 : child: Text(AppLocalizations.of(context)!.okButton),
181 0 : onPressed: () {
182 0 : Navigator.of(context).pop();
183 : },
184 : );
185 :
186 : // set up the AlertDialog
187 0 : AlertDialog alert = AlertDialog(
188 0 : title: Text(AppLocalizations.of(context)!.settingsAndroidPowerReenablePopup),
189 0 : actions: [
190 : okButton,
191 : ],
192 : );
193 :
194 : // show the dialog
195 0 : showDialog(
196 : context: context,
197 0 : builder: (BuildContext context) {
198 : return alert;
199 : },
200 : );
201 : }
202 : }
|