Files
MWClash/lib/fragments/theme.dart
chen08209 50bf4170d9 Optimize DNS strategy
Fix the problem that the tray is not displayed in some cases

Optimize tray

Update core

Fix some error
2024-09-08 20:58:02 +08:00

305 lines
8.5 KiB
Dart

import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/models/models.dart';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../widgets/widgets.dart';
class ThemeModeItem {
final ThemeMode themeMode;
final IconData iconData;
final String label;
const ThemeModeItem({
required this.themeMode,
required this.iconData,
required this.label,
});
}
class ThemeFragment extends StatelessWidget {
const ThemeFragment({super.key});
@override
Widget build(BuildContext context) {
final previewCard = Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: CommonCard(
onPressed: () {},
info: Info(
label: appLocalizations.preview,
iconData: Icons.looks,
),
child: Container(
height: 200,
),
),
);
return SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
previewCard,
const ThemeColorsBox(),
],
),
);
}
}
class ItemCard extends StatelessWidget {
final Widget child;
final Info info;
const ItemCard({
super.key,
required this.info,
required this.child,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
top: 16,
),
child: Wrap(
runSpacing: 16,
children: [
InfoHeader(
info: info,
),
child,
],
),
);
}
}
class ThemeColorsBox extends StatefulWidget {
const ThemeColorsBox({super.key});
@override
State<ThemeColorsBox> createState() => _ThemeColorsBoxState();
}
class _ThemeColorsBoxState extends State<ThemeColorsBox> {
Widget _themeModeCheckBox({
bool? isSelected,
required ThemeModeItem themeModeItem,
}) {
return CommonCard(
isSelected: isSelected,
onPressed: () {
globalState.appController.config.themeMode = themeModeItem.themeMode;
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Flexible(
child: Icon(themeModeItem.iconData),
),
const SizedBox(
width: 8,
),
Flexible(
child: Text(
themeModeItem.label,
),
),
],
),
),
);
}
Widget _primaryColorCheckBox({
bool? isSelected,
Color? color,
}) {
return ColorSchemeBox(
isSelected: isSelected,
primaryColor: color,
onPressed: () {
globalState.appController.config.primaryColor = color?.value;
},
);
}
@override
Widget build(BuildContext context) {
List<ThemeModeItem> themeModeItems = [
ThemeModeItem(
iconData: Icons.auto_mode,
label: appLocalizations.auto,
themeMode: ThemeMode.system,
),
ThemeModeItem(
iconData: Icons.light_mode,
label: appLocalizations.light,
themeMode: ThemeMode.light,
),
ThemeModeItem(
iconData: Icons.dark_mode,
label: appLocalizations.dark,
themeMode: ThemeMode.dark,
),
];
List<Color?> primaryColors = [
null,
defaultPrimaryColor,
Colors.pinkAccent,
Colors.lightBlue,
Colors.greenAccent,
Colors.yellowAccent,
Colors.purple,
];
return Column(
children: [
ItemCard(
info: Info(
label: appLocalizations.themeMode,
iconData: Icons.brightness_high,
),
child: Selector<Config, ThemeMode>(
selector: (_, config) => config.themeMode,
builder: (_, themeMode, __) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
height: 64,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: themeModeItems.length,
itemBuilder: (_, index) {
final themeModeItem = themeModeItems[index];
return _themeModeCheckBox(
isSelected: themeMode == themeModeItem.themeMode,
themeModeItem: themeModeItem,
);
},
separatorBuilder: (_, __) {
return const SizedBox(
width: 16,
);
},
),
);
},
),
),
ItemCard(
info: Info(
label: appLocalizations.themeColor,
iconData: Icons.palette,
),
child: Container(
margin: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 16,
),
height: 88,
child: Selector<Config, int?>(
selector: (_, config) => config.primaryColor,
builder: (_, currentPrimaryColor, __) {
return ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (_, index) {
final primaryColor = primaryColors[index];
return _primaryColorCheckBox(
isSelected: currentPrimaryColor == primaryColor?.value,
color: primaryColor,
);
},
separatorBuilder: (_, __) {
return const SizedBox(
width: 16,
);
},
itemCount: primaryColors.length,
);
},
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Selector<Config, bool>(
selector: (_, config) => config.prueBlack,
builder: (_, value, ___) {
return ListItem.switchItem(
leading: Icon(
Icons.contrast,
color: context.colorScheme.primary,
),
title: Text(appLocalizations.prueBlackMode),
delegate: SwitchDelegate(
value: value,
onChanged: (value) {
globalState.appController.config.prueBlack = value;
}),
);
},
),
),
// Padding(
// padding: const EdgeInsets.symmetric(vertical: 16),
// child: Selector<Config, bool>(
// selector: (_, config) => config.scaleProps.custom,
// builder: (_, value, ___) {
// return ListItem.switchItem(
// leading: Icon(
// Icons.format_size_sharp,
// color: context.colorScheme.primary,
// ),
// title: const Text("自定义字体大小"),
// delegate: SwitchDelegate(
// value: value,
// onChanged: (value) {
// globalState.appController.config.scaleProps =
// globalState.appController.config.scaleProps.copyWith(
// custom: value,
// );
// },
// ),
// );
// },
// ),
// ),
// SizedBox(
// height: 20,
// child: Selector<Config, ScaleProps>(
// selector: (_, config) => config.scaleProps,
// builder: (_, props, ___) {
// return AbsorbPointer(
// absorbing: !props.custom,
// child: DisabledMask(
// status: !props.custom,
// child: Slider(
// value: props.scale,
// min: 0.8,
// max: 1.2,
// onChanged: (value) {
// globalState.appController.config.scaleProps =
// globalState.appController.config.scaleProps.copyWith(
// scale: value,
// );
// },
// ),
// ),
// );
// },
// ),
// ),
const SizedBox(
height: 64,
),
],
);
}
}