Files
MWClash/lib/fragments/theme.dart
chen08209 ef5f6dbd59 Add rule override
Update core

Optimize more details
2025-04-08 15:35:14 +08:00

346 lines
9.1 KiB
Dart

import 'package:fl_clash/common/common.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/providers/config.dart';
import 'package:fl_clash/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class ThemeModeItem {
final ThemeMode themeMode;
final IconData iconData;
final String label;
const ThemeModeItem({
required this.themeMode,
required this.iconData,
required this.label,
});
}
class FontFamilyItem {
final FontFamily fontFamily;
final String label;
const FontFamilyItem({
required this.fontFamily,
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 ConsumerStatefulWidget {
const ThemeColorsBox({super.key});
@override
ConsumerState<ThemeColorsBox> createState() => _ThemeColorsBoxState();
}
class _ThemeColorsBoxState extends ConsumerState<ThemeColorsBox> {
@override
Widget build(BuildContext context) {
return Column(
children: [
// _FontFamilyItem(),
_ThemeModeItem(),
_PrimaryColorItem(),
_PrueBlackItem(),
const SizedBox(
height: 64,
),
],
);
}
}
// class _FontFamilyItem extends ConsumerWidget {
// const _FontFamilyItem();
//
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final fontFamily =
// ref.watch(themeSettingProvider.select((state) => state.fontFamily));
// List<FontFamilyItem> fontFamilyItems = [
// FontFamilyItem(
// label: appLocalizations.systemFont,
// fontFamily: FontFamily.system,
// ),
// const FontFamilyItem(
// label: "roboto",
// fontFamily: FontFamily.roboto,
// ),
// ];
// return ItemCard(
// info: Info(
// label: appLocalizations.fontFamily,
// iconData: Icons.text_fields,
// ),
// child: Container(
// margin: const EdgeInsets.only(
// left: 16,
// right: 16,
// ),
// height: 48,
// child: ListView.separated(
// scrollDirection: Axis.horizontal,
// itemBuilder: (_, index) {
// final fontFamilyItem = fontFamilyItems[index];
// return CommonCard(
// isSelected: fontFamilyItem.fontFamily == fontFamily,
// onPressed: () {
// ref.read(themeSettingProvider.notifier).updateState(
// (state) => state.copyWith(
// fontFamily: fontFamilyItem.fontFamily,
// ),
// );
// },
// child: Padding(
// padding: const EdgeInsets.symmetric(horizontal: 16),
// child: Row(
// mainAxisSize: MainAxisSize.min,
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Flexible(
// child: Text(
// fontFamilyItem.label,
// ),
// ),
// ],
// ),
// ),
// );
// },
// separatorBuilder: (_, __) {
// return const SizedBox(
// width: 16,
// );
// },
// itemCount: fontFamilyItems.length,
// ),
// ),
// );
// }
// }
class _ThemeModeItem extends ConsumerWidget {
const _ThemeModeItem();
@override
Widget build(BuildContext context, WidgetRef ref) {
final themeMode =
ref.watch(themeSettingProvider.select((state) => state.themeMode));
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,
),
];
return ItemCard(
info: Info(
label: appLocalizations.themeMode,
iconData: Icons.brightness_high,
),
child: 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 CommonCard(
isSelected: themeModeItem.themeMode == themeMode,
onPressed: () {
ref.read(themeSettingProvider.notifier).updateState(
(state) => state.copyWith(
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,
),
),
],
),
),
);
},
separatorBuilder: (_, __) {
return const SizedBox(
width: 16,
);
},
),
),
);
}
}
class _PrimaryColorItem extends ConsumerWidget {
const _PrimaryColorItem();
@override
Widget build(BuildContext context, WidgetRef ref) {
final primaryColor =
ref.watch(themeSettingProvider.select((state) => state.primaryColor));
List<Color?> primaryColors = [
null,
defaultPrimaryColor,
Colors.pinkAccent,
Colors.lightBlue,
Colors.greenAccent,
Colors.yellowAccent,
Colors.purple,
];
return ItemCard(
info: Info(
label: appLocalizations.themeColor,
iconData: Icons.palette,
),
child: Container(
margin: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 16,
),
height: 88,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemBuilder: (_, index) {
final color = primaryColors[index];
return ColorSchemeBox(
isSelected: color?.toARGB32() == primaryColor,
primaryColor: color,
onPressed: () {
ref.read(themeSettingProvider.notifier).updateState(
(state) => state.copyWith(
primaryColor: color?.toARGB32(),
),
);
},
);
},
separatorBuilder: (_, __) {
return const SizedBox(
width: 16,
);
},
itemCount: primaryColors.length,
),
),
);
}
}
class _PrueBlackItem extends ConsumerWidget {
const _PrueBlackItem();
@override
Widget build(BuildContext context, WidgetRef ref) {
final prueBlack =
ref.watch(themeSettingProvider.select((state) => state.pureBlack));
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: ListItem.switchItem(
leading: Icon(
Icons.contrast,
color: context.colorScheme.primary,
),
title: Text(appLocalizations.pureBlackMode),
delegate: SwitchDelegate(
value: prueBlack,
onChanged: (value) {
ref.read(themeSettingProvider.notifier).updateState(
(state) => state.copyWith(
pureBlack: value,
),
);
},
),
),
);
}
}