530 lines
18 KiB
Dart
530 lines
18 KiB
Dart
import 'dart:io';
|
||
|
||
import 'package:fluent_ui/fluent_ui.dart' as fluent;
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_dmzj/app/app_color.dart';
|
||
import 'package:flutter_dmzj/app/app_style.dart';
|
||
import 'package:flutter_dmzj/app/platform_utils.dart';
|
||
import 'package:flutter_dmzj/modules/user/settings/settings_controller.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:remixicon/remixicon.dart';
|
||
|
||
class SettingsPage extends StatelessWidget {
|
||
final int index;
|
||
SettingsPage({required this.index, super.key});
|
||
final controller = Get.put<SettingsController>(SettingsController());
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return DefaultTabController(
|
||
length: 4,
|
||
initialIndex: index,
|
||
child: Scaffold(
|
||
appBar: AppBar(
|
||
title: Container(
|
||
alignment: Alignment.center,
|
||
padding: const EdgeInsets.only(right: 56),
|
||
child: TabBar(
|
||
isScrollable: true,
|
||
tabAlignment: TabAlignment.start,
|
||
indicatorSize: TabBarIndicatorSize.label,
|
||
indicatorColor: Theme.of(context).colorScheme.primary,
|
||
labelColor: Theme.of(context).colorScheme.primary,
|
||
unselectedLabelColor:
|
||
Get.isDarkMode ? Colors.white70 : Colors.black87,
|
||
tabs: const [
|
||
Tab(text: "常规"),
|
||
Tab(text: "漫画"),
|
||
Tab(text: "小说"),
|
||
Tab(text: "下载"),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
body: TabBarView(
|
||
children: [
|
||
buildGeneralSettings(),
|
||
buildComicSettings(),
|
||
buildNovelSettings(),
|
||
buildDownloadSettings(),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget buildGeneralSettings() {
|
||
return Obx(
|
||
() => ListView(
|
||
padding: AppStyle.edgeInsetsA12,
|
||
children: [
|
||
buildToggle(
|
||
value: controller.settings.useDynamicColor.value,
|
||
onChanged: (e) {
|
||
controller.settings.setUseDynamicColor(e);
|
||
},
|
||
title: "使用MD动态取色",
|
||
subtitle: "关闭后使用固定主题色 #4196f9",
|
||
),
|
||
ListTile(
|
||
title: const Text("清除图片缓存"),
|
||
subtitle: Text(controller.imageCacheSize.value),
|
||
trailing: OutlinedButton(
|
||
onPressed: () {
|
||
controller.cleanImageCache();
|
||
},
|
||
child: const Text("清除"),
|
||
),
|
||
),
|
||
ListTile(
|
||
title: const Text("清除小说缓存"),
|
||
subtitle: Text(controller.novelCacheSize.value),
|
||
trailing: OutlinedButton(
|
||
onPressed: () {},
|
||
child: const Text("清除"),
|
||
),
|
||
),
|
||
// SwitchListTile(
|
||
// value: controller.settings.comicSearchUseWebApi.value,
|
||
// onChanged: (e) {
|
||
// controller.settings.setComicSearchUseWebApi(e);
|
||
// },
|
||
// title: const Text("使用Web接口搜索漫画"),
|
||
// subtitle: const Text("开启后可以搜索到更多漫画"),
|
||
// ),
|
||
buildToggle(
|
||
value: controller.settings.useSystemFontSize.value,
|
||
onChanged: (e) {
|
||
controller.settings.setUseSystemFontSize(e);
|
||
},
|
||
title: "字体大小跟随系统",
|
||
subtitle: "开启可能会有布局错乱",
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.collectHideComic.value,
|
||
onChanged: (e) {
|
||
controller.settings.setCollectHideComic(e);
|
||
},
|
||
title: "自动收藏神隐漫画",
|
||
subtitle: "浏览神隐漫画时自动添加到本机收藏",
|
||
),
|
||
ListTile(
|
||
title: const Text("代理地址"),
|
||
subtitle: TextField(
|
||
controller: TextEditingController(text: controller.settings.proxyAddress.value),
|
||
decoration: const InputDecoration(
|
||
hintText: "仅支持http协议,重启生效 eg:127.0.0.1:7890",
|
||
),
|
||
onSubmitted: (e){
|
||
controller.settings.setProxyAddress(e);
|
||
},
|
||
),
|
||
|
||
)
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget buildComicSettings() {
|
||
return Obx(
|
||
() => ListView(
|
||
padding: AppStyle.edgeInsetsA12,
|
||
children: [
|
||
buildToggle(
|
||
value: controller.settings.comicReaderHD.value,
|
||
onChanged: (e) {
|
||
controller.settings.setComicReaderHD(e);
|
||
},
|
||
title: "优先加载高清图",
|
||
subtitle: "部分单行本可能未分页",
|
||
),
|
||
ListTile(
|
||
title: const Text("阅读方向"),
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
buildSelectedButton(
|
||
onTap: () {
|
||
controller.settings.setComicReaderDirection(0);
|
||
},
|
||
selected: controller.settings.comicReaderDirection.value == 0,
|
||
child: const Icon(Remix.arrow_right_line),
|
||
),
|
||
AppStyle.hGap8,
|
||
buildSelectedButton(
|
||
onTap: () {
|
||
controller.settings.setComicReaderDirection(2);
|
||
},
|
||
selected: controller.settings.comicReaderDirection.value == 2,
|
||
child: const Icon(Remix.arrow_left_line),
|
||
),
|
||
AppStyle.hGap8,
|
||
buildSelectedButton(
|
||
onTap: () {
|
||
controller.settings.setComicReaderDirection(1);
|
||
},
|
||
selected: controller.settings.comicReaderDirection.value == 1,
|
||
child: const Icon(Remix.arrow_down_line),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.comicReaderLeftHandMode.value,
|
||
onChanged: (e) {
|
||
controller.settings.setComicReaderLeftHandMode(e);
|
||
},
|
||
title: "操作反转",
|
||
subtitle: "点击左侧下一页,右侧上一页",
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.comicReaderFullScreen.value,
|
||
onChanged: (e) {
|
||
controller.settings.setComicReaderFullScreen(e);
|
||
},
|
||
title: "全屏阅读",
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.comicReaderShowStatus.value,
|
||
onChanged: (e) {
|
||
controller.settings.setComicReaderShowStatus(e);
|
||
},
|
||
title: "显示状态信息",
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.comicReaderShowViewPoint.value,
|
||
onChanged: (e) {
|
||
controller.settings.setComicReaderShowViewPoint(e);
|
||
},
|
||
title: "显示吐槽",
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.comicReaderOldViewPoint.value,
|
||
onChanged: (e) {
|
||
controller.settings.setComicReaderOldViewPoint(e);
|
||
},
|
||
title: "旧版吐槽",
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.comicReaderPageAnimation.value,
|
||
onChanged: (e) {
|
||
controller.settings.setComicReaderPageAnimation(e);
|
||
},
|
||
title: "翻页动画",
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget buildNovelSettings() {
|
||
return Obx(
|
||
() => ListView(
|
||
padding: AppStyle.edgeInsetsA12,
|
||
children: [
|
||
ListTile(
|
||
title: const Text("阅读方向"),
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
buildSelectedButton(
|
||
onTap: () {
|
||
controller.settings.setNovelReaderDirection(0);
|
||
},
|
||
selected: controller.settings.novelReaderDirection.value == 0,
|
||
child: const Icon(Remix.arrow_right_line),
|
||
),
|
||
AppStyle.hGap8,
|
||
buildSelectedButton(
|
||
onTap: () {
|
||
controller.settings.setNovelReaderDirection(2);
|
||
},
|
||
selected: controller.settings.novelReaderDirection.value == 2,
|
||
child: const Icon(Remix.arrow_left_line),
|
||
),
|
||
AppStyle.hGap8,
|
||
buildSelectedButton(
|
||
onTap: () {
|
||
controller.settings.setNovelReaderDirection(1);
|
||
},
|
||
selected: controller.settings.novelReaderDirection.value == 1,
|
||
child: const Icon(Remix.arrow_down_line),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.novelReaderLeftHandMode.value,
|
||
onChanged: (e) {
|
||
controller.settings.setNovelReaderLeftHandMode(e);
|
||
},
|
||
title: "操作反转",
|
||
subtitle: "点击左侧下一页,右侧上一页",
|
||
),
|
||
// SwitchListTile(
|
||
// value: settings.novelReaderFullScreen.value,
|
||
// onChanged: (e) {
|
||
// settings.setNovelReaderFullScreen(e);
|
||
// },
|
||
// title: const Text("全屏阅读"),
|
||
// ),
|
||
buildToggle(
|
||
value: controller.settings.novelReaderShowStatus.value,
|
||
onChanged: (e) {
|
||
controller.settings.setNovelReaderShowStatus(e);
|
||
},
|
||
title: "显示状态信息",
|
||
),
|
||
buildToggle(
|
||
value: controller.settings.novelReaderPageAnimation.value,
|
||
onChanged: (e) {
|
||
controller.settings.setNovelReaderPageAnimation(e);
|
||
},
|
||
title: "翻页动画",
|
||
),
|
||
ListTile(
|
||
title: const Text("字体大小"),
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
OutlinedButton(
|
||
onPressed: () {
|
||
controller.settings.setNovelReaderFontSize(
|
||
controller.settings.novelReaderFontSize.value + 1,
|
||
);
|
||
},
|
||
child: const Icon(
|
||
Icons.add,
|
||
),
|
||
),
|
||
AppStyle.hGap12,
|
||
Text("${controller.settings.novelReaderFontSize.value}"),
|
||
AppStyle.hGap12,
|
||
OutlinedButton(
|
||
onPressed: () {
|
||
controller.settings.setNovelReaderFontSize(
|
||
controller.settings.novelReaderFontSize.value - 1,
|
||
);
|
||
},
|
||
child: const Icon(
|
||
Icons.remove,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
ListTile(
|
||
title: const Text("行距"),
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
OutlinedButton(
|
||
onPressed: () {
|
||
controller.settings.setNovelReaderLineSpacing(
|
||
controller.settings.novelReaderLineSpacing.value + 0.1,
|
||
);
|
||
},
|
||
child: const Icon(
|
||
Icons.add,
|
||
),
|
||
),
|
||
AppStyle.hGap12,
|
||
Text((controller.settings.novelReaderLineSpacing.value)
|
||
.toStringAsFixed(1)),
|
||
AppStyle.hGap12,
|
||
OutlinedButton(
|
||
onPressed: () {
|
||
controller.settings.setNovelReaderLineSpacing(
|
||
controller.settings.novelReaderLineSpacing.value - 0.1,
|
||
);
|
||
},
|
||
child: const Icon(
|
||
Icons.remove,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
ListTile(
|
||
title: const Text("阅读主题"),
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: AppColor.novelThemes.keys
|
||
.map(
|
||
(e) => GestureDetector(
|
||
onTap: () {
|
||
controller.settings.setNovelReaderTheme(e);
|
||
},
|
||
child: Container(
|
||
margin: AppStyle.edgeInsetsL8,
|
||
height: 36,
|
||
width: 36,
|
||
decoration: BoxDecoration(
|
||
color: AppColor.novelThemes[e]!.first,
|
||
borderRadius: AppStyle.radius24,
|
||
),
|
||
child: Visibility(
|
||
visible:
|
||
AppColor.novelThemes.keys.toList().indexOf(e) ==
|
||
controller.settings.novelReaderTheme.value,
|
||
child: Icon(
|
||
Icons.check,
|
||
color: AppColor.novelThemes[e]!.last,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
)
|
||
.toList(),
|
||
),
|
||
),
|
||
Container(
|
||
margin: AppStyle.edgeInsetsV12,
|
||
padding: AppStyle.edgeInsetsA8,
|
||
decoration: BoxDecoration(
|
||
borderRadius: AppStyle.radius4,
|
||
color: AppColor
|
||
.novelThemes[controller.settings.novelReaderTheme]!.first,
|
||
),
|
||
child: Text(
|
||
"""这是一段测试文字,可以预览上面的设置效果。
|
||
|
||
晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。
|
||
林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐……""",
|
||
//不需要跟随系统
|
||
textScaler: const TextScaler.linear(1.0),
|
||
style: TextStyle(
|
||
fontSize:
|
||
controller.settings.novelReaderFontSize.value.toDouble(),
|
||
height: controller.settings.novelReaderLineSpacing.value,
|
||
color: AppColor
|
||
.novelThemes[controller.settings.novelReaderTheme]!.last,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget buildDownloadSettings() {
|
||
return Obx(
|
||
() => ListView(
|
||
padding: AppStyle.edgeInsetsA12,
|
||
children: [
|
||
buildToggle(
|
||
value: controller.settings.downloadAllowCellular.value,
|
||
onChanged: (e) {
|
||
controller.settings.setDownloadAllowCellular(e);
|
||
},
|
||
title: "允许使用流量下载",
|
||
),
|
||
ListTile(
|
||
title: const Text("漫画最大任务数"),
|
||
onTap: () {
|
||
controller.setDownloadComicTask();
|
||
},
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
Text(
|
||
controller.settings.downloadComicTaskCount.value == 0
|
||
? "无限制"
|
||
: controller.settings.downloadComicTaskCount.toString(),
|
||
),
|
||
AppStyle.hGap4,
|
||
const Icon(
|
||
Icons.chevron_right,
|
||
color: Colors.grey,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
ListTile(
|
||
title: const Text("小说最大任务数"),
|
||
onTap: () {
|
||
controller.setDownloadNovelTask();
|
||
},
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
Text(
|
||
controller.settings.downloadNovelTaskCount.value == 0
|
||
? "无限制"
|
||
: controller.settings.downloadNovelTaskCount.toString(),
|
||
),
|
||
AppStyle.hGap4,
|
||
const Icon(
|
||
Icons.chevron_right,
|
||
color: Colors.grey,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget buildSelectedButton(
|
||
{required Widget child, bool selected = false, Function()? onTap}) {
|
||
final primary = Get.theme.colorScheme.primary;
|
||
return OutlinedButton(
|
||
style: OutlinedButton.styleFrom(
|
||
foregroundColor: selected ? primary : Colors.grey,
|
||
side: BorderSide(
|
||
color: selected ? primary : Colors.grey,
|
||
),
|
||
),
|
||
onPressed: onTap,
|
||
child: child,
|
||
);
|
||
}
|
||
|
||
/// 平台自适应开关控件
|
||
/// Windows使用Fluent ToggleSwitch,其他平台使用Material SwitchListTile
|
||
Widget buildToggle({
|
||
required String title,
|
||
required bool value,
|
||
required ValueChanged<bool> onChanged,
|
||
String? subtitle,
|
||
}) {
|
||
if (PlatformUtils.isWindows) {
|
||
return Padding(
|
||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||
child: Row(
|
||
children: [
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(title,
|
||
style: Get.textTheme.bodyMedium),
|
||
if (subtitle != null)
|
||
Text(subtitle,
|
||
style: Get.textTheme.bodySmall
|
||
?.copyWith(color: Colors.grey)),
|
||
],
|
||
),
|
||
),
|
||
fluent.FluentTheme(
|
||
data: PlatformUtils.getFluentTheme(Get.context!),
|
||
child: fluent.ToggleSwitch(
|
||
checked: value,
|
||
onChanged: onChanged,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
return SwitchListTile(
|
||
value: value,
|
||
onChanged: onChanged,
|
||
title: Text(title),
|
||
subtitle: subtitle != null ? Text(subtitle) : null,
|
||
);
|
||
}
|
||
}
|