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