491fae10f5
BREAKING CHANGE: DNS and NTP override toggles are removed; picked keys apply to every profile Changelog: Per-key DNS, NTP, sniffer and TUN settings
342 lines
11 KiB
Dart
342 lines
11 KiB
Dart
import 'package:fl_clash/common/common.dart';
|
|
import 'package:fl_clash/enum/enum.dart';
|
|
import 'package:fl_clash/icons/icons.dart';
|
|
import 'package:fl_clash/providers/config.dart';
|
|
import 'package:fl_clash/widgets/widgets.dart';
|
|
import 'package:material_ui/material_ui.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
class ProxiesSetting extends StatelessWidget {
|
|
const ProxiesSetting({super.key});
|
|
|
|
Glyph _getIconWithProxiesType(ProxiesType type) {
|
|
return switch (type) {
|
|
ProxiesType.tab => AppGlyphs.layoutTabs,
|
|
ProxiesType.list => AppGlyphs.layoutList,
|
|
};
|
|
}
|
|
|
|
Glyph _getIconWithProxiesSortType(ProxiesSortType type) {
|
|
return switch (type) {
|
|
ProxiesSortType.none => AppGlyphs.sort,
|
|
ProxiesSortType.delay => AppGlyphs.bolt,
|
|
ProxiesSortType.name => AppGlyphs.sortAlpha,
|
|
};
|
|
}
|
|
|
|
String _getStringProxiesSortType(BuildContext context, ProxiesSortType type) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return switch (type) {
|
|
ProxiesSortType.none => appLocalizations.defaultText,
|
|
ProxiesSortType.delay => appLocalizations.delay,
|
|
ProxiesSortType.name => appLocalizations.name,
|
|
};
|
|
}
|
|
|
|
String getTextForProxiesLayout(
|
|
BuildContext context,
|
|
ProxiesLayout proxiesLayout,
|
|
) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return switch (proxiesLayout) {
|
|
ProxiesLayout.tight => appLocalizations.tight,
|
|
ProxiesLayout.standard => appLocalizations.standard,
|
|
ProxiesLayout.loose => appLocalizations.loose,
|
|
};
|
|
}
|
|
|
|
String _getTextWithProxiesIconStyle(
|
|
BuildContext context,
|
|
ProxiesIconStyle style,
|
|
) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return switch (style) {
|
|
ProxiesIconStyle.filled => appLocalizations.iconStyleFilled,
|
|
ProxiesIconStyle.plain => appLocalizations.iconStylePlain,
|
|
ProxiesIconStyle.hidden => appLocalizations.iconStyleHidden,
|
|
};
|
|
}
|
|
|
|
Glyph _getIconWithProxiesLayout(ProxiesLayout proxiesLayout) {
|
|
return switch (proxiesLayout) {
|
|
ProxiesLayout.tight => AppGlyphs.columnsThree,
|
|
ProxiesLayout.standard => AppGlyphs.columnsTwo,
|
|
ProxiesLayout.loose => AppGlyphs.columnsOne,
|
|
};
|
|
}
|
|
|
|
Glyph _getIconWithProxyCardType(ProxyCardType type) {
|
|
return switch (type) {
|
|
ProxyCardType.expand => AppGlyphs.cardLarge,
|
|
ProxyCardType.shrink => AppGlyphs.cardMedium,
|
|
ProxyCardType.min => AppGlyphs.cardSmall,
|
|
};
|
|
}
|
|
|
|
Glyph _getIconWithProxiesIconStyle(ProxiesIconStyle style) {
|
|
return switch (style) {
|
|
ProxiesIconStyle.filled => AppGlyphs.iconTile,
|
|
ProxiesIconStyle.plain => AppGlyphs.iconPlain,
|
|
ProxiesIconStyle.hidden => AppGlyphs.eyeOff,
|
|
};
|
|
}
|
|
|
|
List<Widget> _buildStyleSetting(BuildContext context) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return generateSection(
|
|
isFirst: true,
|
|
title: appLocalizations.style,
|
|
items: [
|
|
SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
scrollDirection: Axis.horizontal,
|
|
child: Consumer(
|
|
builder: (_, ref, _) {
|
|
final proxiesType = ref.watch(
|
|
proxiesStyleSettingProvider.select((state) => state.type),
|
|
);
|
|
return Wrap(
|
|
spacing: 16,
|
|
children: [
|
|
for (final item in ProxiesType.values)
|
|
SettingInfoCard(
|
|
Info(
|
|
label: item.label,
|
|
glyph: _getIconWithProxiesType(item),
|
|
),
|
|
isSelected: proxiesType == item,
|
|
onPressed: () {
|
|
ref.read(proxiesStyleSettingProvider.notifier).update((
|
|
state,
|
|
) {
|
|
return state.copyWith(type: item);
|
|
});
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
List<Widget> _buildSortSetting(BuildContext context) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return generateSection(
|
|
title: appLocalizations.sort,
|
|
items: [
|
|
SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
scrollDirection: Axis.horizontal,
|
|
child: Consumer(
|
|
builder: (_, ref, _) {
|
|
final sortType = ref.watch(
|
|
proxiesStyleSettingProvider.select((state) => state.sortType),
|
|
);
|
|
return Wrap(
|
|
spacing: 16,
|
|
children: [
|
|
for (final item in ProxiesSortType.values)
|
|
SettingInfoCard(
|
|
Info(
|
|
label: _getStringProxiesSortType(context, item),
|
|
glyph: _getIconWithProxiesSortType(item),
|
|
),
|
|
isSelected: sortType == item,
|
|
onPressed: () {
|
|
ref.read(proxiesStyleSettingProvider.notifier).update((
|
|
state,
|
|
) {
|
|
return state.copyWith(sortType: item);
|
|
});
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
List<Widget> _buildSizeSetting(BuildContext context) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return generateSection(
|
|
title: appLocalizations.size,
|
|
items: [
|
|
SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
scrollDirection: Axis.horizontal,
|
|
child: Consumer(
|
|
builder: (_, ref, _) {
|
|
final cardType = ref.watch(
|
|
proxiesStyleSettingProvider.select((state) => state.cardType),
|
|
);
|
|
return Wrap(
|
|
spacing: 16,
|
|
children: [
|
|
for (final item in ProxyCardType.values)
|
|
SettingInfoCard(
|
|
Info(
|
|
label: item.label,
|
|
glyph: _getIconWithProxyCardType(item),
|
|
),
|
|
isSelected: item == cardType,
|
|
onPressed: () {
|
|
ref.read(proxiesStyleSettingProvider.notifier).update((
|
|
state,
|
|
) {
|
|
return state.copyWith(cardType: item);
|
|
});
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
List<Widget> _buildLayoutSetting(BuildContext context) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return generateSection(
|
|
title: appLocalizations.layout,
|
|
items: [
|
|
SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
scrollDirection: Axis.horizontal,
|
|
child: Consumer(
|
|
builder: (_, ref, _) {
|
|
final layout = ref.watch(
|
|
proxiesStyleSettingProvider.select((state) => state.layout),
|
|
);
|
|
return Wrap(
|
|
spacing: 16,
|
|
children: [
|
|
for (final item in ProxiesLayout.values)
|
|
SettingInfoCard(
|
|
Info(
|
|
label: getTextForProxiesLayout(context, item),
|
|
glyph: _getIconWithProxiesLayout(item),
|
|
),
|
|
isSelected: item == layout,
|
|
onPressed: () {
|
|
ref.watch(proxiesStyleSettingProvider.notifier).update((
|
|
state,
|
|
) {
|
|
return state.copyWith(layout: item);
|
|
});
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
List<Widget> _buildGroupStyleSetting(BuildContext context) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return generateSection(
|
|
title: appLocalizations.iconStyle,
|
|
items: [
|
|
SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
scrollDirection: Axis.horizontal,
|
|
child: Consumer(
|
|
builder: (_, ref, _) {
|
|
final iconStyle = ref.watch(
|
|
proxiesStyleSettingProvider.select((state) => state.iconStyle),
|
|
);
|
|
return Wrap(
|
|
spacing: 16,
|
|
children: [
|
|
for (final item in ProxiesIconStyle.values)
|
|
SettingInfoCard(
|
|
Info(
|
|
label: _getTextWithProxiesIconStyle(context, item),
|
|
glyph: _getIconWithProxiesIconStyle(item),
|
|
),
|
|
isSelected: iconStyle == item,
|
|
onPressed: () {
|
|
ref.read(proxiesStyleSettingProvider.notifier).update((
|
|
state,
|
|
) {
|
|
return state.copyWith(iconStyle: item);
|
|
});
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
List<Widget> _buildFilterSetting(BuildContext context) {
|
|
final appLocalizations = context.appLocalizations;
|
|
return generateSection(
|
|
title: appLocalizations.filter,
|
|
items: [
|
|
ConfigToggleItem(
|
|
title: (l) => l.hideTimeoutProxies,
|
|
subtitle: (l) => l.hideTimeoutProxiesDesc,
|
|
selector: proxiesStyleSettingProvider.select(
|
|
(state) => state.hideTimeoutProxies,
|
|
),
|
|
onChanged: (ref, value) {
|
|
ref
|
|
.read(proxiesStyleSettingProvider.notifier)
|
|
.update((state) => state.copyWith(hideTimeoutProxies: value));
|
|
},
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SingleChildScrollView(
|
|
padding: EdgeInsets.only(top: context.contentTopPadding, bottom: 32),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
..._buildStyleSetting(context),
|
|
..._buildSortSetting(context),
|
|
..._buildLayoutSetting(context),
|
|
..._buildSizeSetting(context),
|
|
Consumer(
|
|
builder: (_, ref, child) {
|
|
final isList = ref.watch(
|
|
proxiesStyleSettingProvider.select(
|
|
(state) => state.type == ProxiesType.list,
|
|
),
|
|
);
|
|
if (isList) {
|
|
return child!;
|
|
}
|
|
return Container();
|
|
},
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [..._buildGroupStyleSetting(context)],
|
|
),
|
|
),
|
|
..._buildFilterSetting(context),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|