import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../cwtch_icons_icons.dart'; import '../settings.dart'; import '../themes/opaque.dart'; import 'globalsettingsview.dart'; class GlobalSettingsBehaviourView extends StatefulWidget { @override _GlobalSettingsBehaviourViewState createState() => _GlobalSettingsBehaviourViewState(); } class _GlobalSettingsBehaviourViewState extends State { static const androidSettingsChannel = const MethodChannel('androidSettings'); static const androidSettingsChangeChannel = const MethodChannel('androidSettingsChanged'); ScrollController settingsListScrollController = ScrollController(); bool powerExempt = false; @override void initState() { super.initState(); androidSettingsChangeChannel.setMethodCallHandler(handleSettingsChanged); if (Platform.isAndroid) { isBatteryExempt().then((value) => setState(() { powerExempt = value; })); } else { powerExempt = false; } } // Handler on method channel for MainActivity/onActivityResult to report the user choice when we ask for power exemption Future handleSettingsChanged(MethodCall call) async { if (call.method == "powerExemptionChange") { if (call.arguments) { setState(() { powerExempt = true; }); } } } //* Android Only Requests Future isBatteryExempt() async { return await androidSettingsChannel.invokeMethod('isBatteryExempt', {}) ?? false; } Future requestBatteryExemption() async { await androidSettingsChannel.invokeMethod('requestBatteryExemption', {}); return Future.value(); } //* End Android Only Requests Widget build(BuildContext context) { return Consumer(builder: (ccontext, settings, child) { return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) { return Scrollbar( key: Key("BehaviourSettingsView"), trackVisibility: true, controller: settingsListScrollController, child: SingleChildScrollView( clipBehavior: Clip.antiAlias, controller: settingsListScrollController, child: ConstrainedBox( constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight, maxWidth: viewportConstraints.maxWidth), child: Container( color: settings.theme.backgroundPaneColor, child: Column(children: [ Visibility( visible: Platform.isAndroid, child: SwitchListTile( title: Text(AppLocalizations.of(context)!.settingAndroidPowerExemption), subtitle: Text(AppLocalizations.of(context)!.settingAndroidPowerExemptionDescription), value: powerExempt, onChanged: (bool value) { if (value) { requestBatteryExemption(); } else { // We can't ask for it to be turned off, show an informational popup showBatteryDialog(context); } }, activeTrackColor: settings.theme.defaultButtonColor, inactiveTrackColor: settings.theme.defaultButtonDisabledColor, secondary: Icon(Icons.power, color: settings.current().mainTextColor), ), ), ListTile( title: Text(AppLocalizations.of(context)!.notificationPolicySettingLabel), subtitle: Text(AppLocalizations.of(context)!.notificationPolicySettingDescription), trailing: Container( width: MediaQuery.of(context).size.width / 4, child: DropdownButton( isExpanded: true, value: settings.notificationPolicy, onChanged: (NotificationPolicy? newValue) { settings.notificationPolicy = newValue!; saveSettings(context); }, items: NotificationPolicy.values.map>((NotificationPolicy value) { return DropdownMenuItem( value: value, child: Text(Settings.notificationPolicyToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), ); }).toList())), leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor), ), ListTile( title: Text(AppLocalizations.of(context)!.notificationContentSettingLabel), subtitle: Text(AppLocalizations.of(context)!.notificationContentSettingDescription), trailing: Container( width: MediaQuery.of(context).size.width / 4, child: DropdownButton( isExpanded: true, value: settings.notificationContent, onChanged: (NotificationContent? newValue) { settings.notificationContent = newValue!; saveSettings(context); }, items: NotificationContent.values.map>((NotificationContent value) { return DropdownMenuItem( value: value, child: Text(Settings.notificationContentToString(value, context), overflow: TextOverflow.ellipsis, style: settings.scaleFonts(defaultDropDownMenuItemTextStyle)), ); }).toList())), leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor), ), SwitchListTile( title: Text(AppLocalizations.of(context)!.blockUnknownLabel), subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections), value: settings.blockUnknownConnections, onChanged: (bool value) { if (value) { settings.forbidUnknownConnections(); } else { settings.allowUnknownConnections(); } // Save Settings... saveSettings(context); }, activeTrackColor: settings.theme.defaultButtonColor, inactiveTrackColor: settings.theme.defaultButtonDisabledColor, secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor), ), SwitchListTile( title: Text(AppLocalizations.of(context)!.defaultPreserveHistorySetting), subtitle: Text(AppLocalizations.of(context)!.preserveHistorySettingDescription), value: settings.preserveHistoryByDefault, onChanged: (bool value) { if (value) { settings.setPreserveHistoryDefault(); } else { settings.setDeleteHistoryDefault(); } // Save Settings... saveSettings(context); }, activeTrackColor: settings.theme.defaultButtonColor, inactiveTrackColor: settings.theme.defaultButtonDisabledColor, secondary: Icon(CwtchIcons.peer_history, color: settings.current().mainTextColor), ), ]))))); }); }); } showBatteryDialog(BuildContext context) { Widget okButton = ElevatedButton( child: Text(AppLocalizations.of(context)!.okButton), onPressed: () { Navigator.of(context).pop(); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text(AppLocalizations.of(context)!.settingsAndroidPowerReenablePopup), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } }