Added customization screen

This commit is contained in:
Juan Gilsanz Polo 2022-10-26 14:26:09 +02:00
parent f1a837dc42
commit ddb9130769
14 changed files with 518 additions and 93 deletions

View file

@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
class ColorItem extends StatelessWidget {
final Color color;
final int numericValue;
final int? selectedValue;
final void Function(int) onChanged;
const ColorItem({
Key? key,
required this.color,
required this.numericValue,
required this.selectedValue,
required this.onChanged
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10),
child: Material(
borderRadius: BorderRadius.circular(50),
child: InkWell(
onTap: () => onChanged(numericValue),
borderRadius: BorderRadius.circular(50),
overlayColor: const MaterialStatePropertyAll(Colors.grey),
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: color.withOpacity(0.6),
borderRadius: BorderRadius.circular(50)
),
child: selectedValue != null && selectedValue == numericValue
? Icon(
Icons.check,
size: 30,
color: color.computeLuminance() > 0.5 ? Colors.black : Colors.white,
)
: null,
),
),
),
);
}
}

View file

@ -0,0 +1,182 @@
import 'package:adguard_home_manager/functions/generate_color_translation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/screens/settings/customization/color_item.dart';
import 'package:adguard_home_manager/screens/settings/customization/theme_mode_button.dart';
import 'package:adguard_home_manager/widgets/custom_switch_list_tile.dart';
import 'package:adguard_home_manager/widgets/section_label.dart';
import 'package:adguard_home_manager/providers/app_config_provider.dart';
import 'package:adguard_home_manager/constants/colors.dart';
class Customization extends StatelessWidget {
const Customization({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final appConfigProvider = Provider.of<AppConfigProvider>(context);
return CustomizationWidget(
appConfigProvider: appConfigProvider
);
}
}
class CustomizationWidget extends StatefulWidget {
final AppConfigProvider appConfigProvider;
const CustomizationWidget({
Key? key,
required this.appConfigProvider,
}) : super(key: key);
@override
State<CustomizationWidget> createState() => _CustomizationWidgetState();
}
class _CustomizationWidgetState extends State<CustomizationWidget> {
int selectedTheme = 0;
bool dynamicColor = true;
int selectedColor = 0;
@override
void initState() {
selectedTheme = widget.appConfigProvider.selectedTheme == ThemeMode.light ? 1 : 2;
dynamicColor = widget.appConfigProvider.useDynamicColor;
selectedColor = widget.appConfigProvider.staticColor;
super.initState();
}
@override
Widget build(BuildContext context) {
final appConfigProvider = Provider.of<AppConfigProvider>(context);
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.customization),
),
body: ListView(
children: [
SectionLabel(label: AppLocalizations.of(context)!.theme),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ThemeModeButton(
icon: Icons.light_mode,
value: 1,
selected: selectedTheme,
label: AppLocalizations.of(context)!.light,
onChanged: (value) {
selectedTheme = value;
appConfigProvider.setSelectedTheme(value);
}
),
ThemeModeButton(
icon: Icons.dark_mode,
value: 2,
selected: selectedTheme,
label: AppLocalizations.of(context)!.dark,
onChanged: (value) {
selectedTheme = value;
appConfigProvider.setSelectedTheme(value);
}
),
],
),
SectionLabel(
label: AppLocalizations.of(context)!.color,
padding: const EdgeInsets.only(top: 45, left: 25, right: 25, bottom: 5),
),
if (appConfigProvider.androidDeviceInfo != null && appConfigProvider.androidDeviceInfo!.version.sdkInt! >= 31) CustomSwitchListTile(
value: dynamicColor,
onChanged: (value) {
setState(() => dynamicColor = value);
appConfigProvider.setUseDynamicColor(value);
},
title: AppLocalizations.of(context)!.useDynamicTheme,
),
if (dynamicColor == false) ...[
SizedBox(
width: MediaQuery.of(context).size.width,
height: 70,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: colors.length,
itemBuilder: (context, index) {
if (index == 0) {
return Row(
children: [
const SizedBox(width: 15),
ColorItem(
color: colors[index],
numericValue: index,
selectedValue: selectedColor,
onChanged: (value) {
setState(() => selectedColor = value);
appConfigProvider.setStaticColor(value);
}
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
width: 1,
height: 60,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(1)
),
)
],
);
}
else if (index == colors.length-1) {
return Row(
children: [
ColorItem(
color: colors[index],
numericValue: index,
selectedValue: selectedColor,
onChanged: (value) {
setState(() => selectedColor = value);
appConfigProvider.setStaticColor(value);
}
),
const SizedBox(width: 15)
],
);
}
else {
return ColorItem(
color: colors[index],
numericValue: index,
selectedValue: selectedColor,
onChanged: (value) {
setState(() => selectedColor = value);
appConfigProvider.setStaticColor(value);
}
);
}
},
),
),
Padding(
padding: const EdgeInsets.only(
left: 25,
top: 10
),
child: Text(
colorTranslation(context, selectedColor!),
style: TextStyle(
color: Theme.of(context).listTileTheme.iconColor,
fontSize: 16
),
),
)
]
],
),
);
}
}

View file

@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
class ThemeModeButton extends StatelessWidget {
final IconData icon;
final int value;
final int selected;
final String label;
final void Function(int) onChanged;
const ThemeModeButton({
Key? key,
required this.icon,
required this.value,
required this.selected,
required this.label,
required this.onChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
borderRadius: BorderRadius.circular(16),
child: InkWell(
onTap: () => onChanged(value),
borderRadius: BorderRadius.circular(16),
child: AnimatedContainer(
padding: const EdgeInsets.all(10),
width: 150,
height: 150,
duration: const Duration(milliseconds: 200),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: value == selected
? Theme.of(context).primaryColor
: Theme.of(context).primaryColor.withOpacity(0.1),
border: Border.all(
color: Theme.of(context).primaryColor
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(
icon,
color: value == selected
? Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white
: null,
size: 30,
),
Text(
label,
style: TextStyle(
color: value == selected
? Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white
: null,
fontSize: 18
),
)
],
),
),
),
);
}
}

View file

@ -4,10 +4,10 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_web_browser/flutter_web_browser.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/screens/settings/theme_modal.dart';
import 'package:adguard_home_manager/screens/settings/server_info/server_info.dart';
import 'package:adguard_home_manager/screens/settings/encryption/encryption.dart';
import 'package:adguard_home_manager/screens/settings/access_settings/access_settings.dart';
import 'package:adguard_home_manager/screens/settings/customization/customization.dart';
import 'package:adguard_home_manager/screens/settings/dhcp/dhcp.dart';
import 'package:adguard_home_manager/widgets/section_label.dart';
import 'package:adguard_home_manager/screens/settings/dns/dns.dart';
@ -32,36 +32,6 @@ class Settings extends StatelessWidget {
final appConfigProvider = Provider.of<AppConfigProvider>(context);
final serversProvider = Provider.of<ServersProvider>(context);
final statusBarHeight = MediaQuery.of(context).viewInsets.top;
String getThemeString() {
switch (appConfigProvider.selectedThemeNumber) {
case 0:
return AppLocalizations.of(context)!.systemDefined;
case 1:
return AppLocalizations.of(context)!.light;
case 2:
return AppLocalizations.of(context)!.dark;
default:
return "";
}
}
void openThemeModal() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => ThemeModal(
statusBarHeight: statusBarHeight,
selectedTheme: appConfigProvider.selectedThemeNumber,
),
backgroundColor: Colors.transparent,
);
}
void navigateServers() {
Future.delayed(const Duration(milliseconds: 0), (() {
Navigator.of(context).push(
@ -167,10 +137,12 @@ class Settings extends StatelessWidget {
],
SectionLabel(label: AppLocalizations.of(context)!.appSettings),
CustomListTile(
icon: Icons.light_mode_rounded,
title: AppLocalizations.of(context)!.theme,
subtitle: getThemeString(),
onTap: openThemeModal,
icon: Icons.palette_rounded,
title: AppLocalizations.of(context)!.customization,
subtitle: AppLocalizations.of(context)!.customizationDescription,
onTap: () => Navigator.push(context, MaterialPageRoute(
builder: (context) => const Customization()
))
),
CustomListTile(
icon: Icons.storage_rounded,