flutter_app/lib/views/globalsettingsview.dart

210 lines
9.8 KiB
Dart

import 'dart:convert';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:cwtch/opaque.dart';
import 'package:cwtch/settings.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../main.dart';
/// Global Settings View provides access to modify all the Globally Relevant Settings including Locale, Theme and Experiments.
class GlobalSettingsView extends StatefulWidget {
@override
_GlobalSettingsViewState createState() => _GlobalSettingsViewState();
}
class _GlobalSettingsViewState extends State<GlobalSettingsView> {
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context).cwtchSettingsTitle),
),
body: _buildSettingsList(),
);
}
Widget _buildSettingsList() {
return Consumer<Settings>(builder: (context, settings, child) {
return LayoutBuilder(builder: (BuildContext context, BoxConstraints viewportConstraints) {
return Scrollbar(
isAlwaysShown: true,
child: SingleChildScrollView(
clipBehavior: Clip.antiAlias,
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Column(children: [
ListTile(
title: Text(AppLocalizations.of(context).settingLanguage, style: TextStyle(color: settings.current().mainTextColor())),
leading: Icon(Icons.language, color: settings.current().mainTextColor()),
trailing: DropdownButton(
value: Provider.of<Settings>(context).locale.languageCode,
onChanged: (String newValue) {
setState(() {
settings.switchLocale(Locale(newValue, ''));
saveSettings(context);
});
},
items: AppLocalizations.supportedLocales.map<DropdownMenuItem<String>>((Locale value) {
return DropdownMenuItem<String>(
value: value.languageCode,
child: Text(getLanguageFull(context, value.languageCode)),
);
}).toList())),
SwitchListTile(
title: Text(AppLocalizations.of(context).settingTheme, style: TextStyle(color: settings.current().mainTextColor())),
value: settings.current() == Opaque.light,
onChanged: (bool value) {
if (value) {
settings.setLight();
} else {
settings.setDark();
}
// Save Settings...
saveSettings(context);
},
secondary: Icon(Icons.lightbulb_outline, color: settings.current().mainTextColor()),
),
ListTile(
title: Text(/*AppLocalizations.of(context).settingLanguage*/ "UI Columns", style: TextStyle(color: settings.current().mainTextColor())),
leading: Icon(Icons.table_chart, color: settings.current().mainTextColor()),
trailing: DropdownButton(
value: "Single",
onChanged: (String newValue) {
if (newValue == "Double (1:2)") {
Provider.of<FlwtchState>(context).columns = [1, 2];
} else if (newValue == "Double (1:4)") {
Provider.of<FlwtchState>(context).columns = [1, 4];
} else {
Provider.of<FlwtchState>(context).columns = [1];
}
},
items: ["Single", "Double (1:2)", "Double (1:4)"].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList())),
SwitchListTile(
title: Text(AppLocalizations.of(context).blockUnknownLabel, style: TextStyle(color: settings.current().mainTextColor())),
subtitle: Text(AppLocalizations.of(context).descriptionBlockUnknownConnections),
value: settings.blockUnknownConnections,
onChanged: (bool value) {
if (value) {
settings.forbidUnknownConnections();
} else {
settings.allowUnknownConnections();
}
// Save Settings...
saveSettings(context);
},
secondary: Icon(Icons.app_blocking, color: settings.current().mainTextColor()),
),
SwitchListTile(
title: Text(AppLocalizations.of(context).experimentsEnabled, style: TextStyle(color: settings.current().mainTextColor())),
subtitle: Text(AppLocalizations.of(context).descriptionExperiments),
value: settings.experimentsEnabled,
onChanged: (bool value) {
if (value) {
settings.enableExperiments();
} else {
settings.disableExperiments();
}
// Save Settings...
saveSettings(context);
},
secondary: Icon(Icons.science, color: settings.current().mainTextColor()),
),
Visibility(
visible: settings.experimentsEnabled,
child: Column(
children: [
SwitchListTile(
title: Text(AppLocalizations.of(context).enableGroups, style: TextStyle(color: settings.current().mainTextColor())),
subtitle: Text(AppLocalizations.of(context).descriptionExperimentsGroups),
value: settings.experiments.containsKey(TapirGroupsExperiment) && settings.experiments[TapirGroupsExperiment],
onChanged: (bool value) {
if (value) {
settings.enableExperiment(TapirGroupsExperiment);
} else {
settings.disableExperiment(TapirGroupsExperiment);
}
// Save Settings...
saveSettings(context);
},
secondary: Icon(Icons.group_sharp, color: settings.current().mainTextColor()),
),
],
)),
AboutListTile(
icon: Icon(Icons.info, color: settings.current().mainTextColor()),
applicationIcon: Padding(
padding: EdgeInsets.all(20),
child: Image(
image: AssetImage("assets/knott.png"),
width: 128,
height: 128,
)),
applicationName: "Cwtch (Flutter UI)",
applicationVersion: AppLocalizations.of(context).version.replaceAll("%1", constructVersionString(Provider.of<Settings>(context).packageInfo)),
applicationLegalese: '\u{a9} 2021 Open Privacy Research Society',
),
]))));
});
});
}
}
/// Construct a version string from Package Info
String constructVersionString(PackageInfo pinfo) {
if (pinfo == null) {
return "";
}
return pinfo.version + "." + pinfo.buildNumber;
}
/// A slightly verbose way to extract the full language name from
/// an individual language code. There might be a more efficient way of doing this.
String getLanguageFull(context, String languageCode) {
if (languageCode == "en") {
return AppLocalizations.of(context).localeEn;
}
if (languageCode == "es") {
return AppLocalizations.of(context).localeEs;
}
if (languageCode == "fr") {
return AppLocalizations.of(context).localeFr;
}
if (languageCode == "pt") {
return AppLocalizations.of(context).localePt;
}
if (languageCode == "de") {
return AppLocalizations.of(context).localeDe;
}
if (languageCode == "it") {
return AppLocalizations.of(context).localeIt;
}
return languageCode;
}
/// Send an UpdateGlobalSettings to the Event Bus
saveSettings(context) {
var settings = Provider.of<Settings>(context, listen: false);
final updateSettingsEvent = {
"EventType": "UpdateGlobalSettings",
"Data": {"Data": jsonEncode(settings.asJson())},
};
final updateSettingsEventJson = jsonEncode(updateSettingsEvent);
Provider.of<FlwtchState>(context, listen: false).cwtch.SendAppEvent(updateSettingsEventJson);
}