feat: 图片清晰度选择

This commit is contained in:
guozhigq
2023-08-11 14:47:48 +08:00
parent 4458e13787
commit f4dc4be811
8 changed files with 176 additions and 39 deletions

View File

@ -1,6 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/constants.dart';
import 'package:pilipala/utils/storage.dart';
Box setting = GStrorage.setting;
class NetworkImgLayer extends StatelessWidget { class NetworkImgLayer extends StatelessWidget {
final String? src; final String? src;
@ -24,13 +28,17 @@ class NetworkImgLayer extends StatelessWidget {
this.fadeOutDuration, this.fadeOutDuration,
this.fadeInDuration, this.fadeInDuration,
// 图片质量 默认1% // 图片质量 默认1%
this.quality = 1, this.quality,
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
double pr = MediaQuery.of(context).devicePixelRatio; double pr = MediaQuery.of(context).devicePixelRatio;
int picQuality = setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10);
// double pr = 2; // double pr = 2;
print(
'${src!.startsWith('//') ? 'https:${src!}' : src!}@${quality ?? picQuality}q.webp');
return src != '' return src != ''
? ClipRRect( ? ClipRRect(
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
@ -41,7 +49,7 @@ class NetworkImgLayer extends StatelessWidget {
: StyleString.imgRadius.x), : StyleString.imgRadius.x),
child: CachedNetworkImage( child: CachedNetworkImage(
imageUrl: imageUrl:
'${src!.startsWith('//') ? 'https:${src!}' : src!}@${quality}q.webp', '${src!.startsWith('//') ? 'https:${src!}' : src!}@${quality ?? picQuality}q.webp',
width: width ?? double.infinity, width: width ?? double.infinity,
height: height ?? double.infinity, height: height ?? double.infinity,
alignment: Alignment.center, alignment: Alignment.center,

View File

@ -11,10 +11,12 @@ import 'package:pilipala/utils/storage.dart';
class SettingController extends GetxController { class SettingController extends GetxController {
Box user = GStrorage.user; Box user = GStrorage.user;
RxBool userLogin = false.obs;
Box userInfoCache = GStrorage.userInfo;
Box setting = GStrorage.setting; Box setting = GStrorage.setting;
Box userInfoCache = GStrorage.userInfo;
RxBool userLogin = false.obs;
RxBool feedBackEnable = false.obs; RxBool feedBackEnable = false.obs;
RxInt picQuality = 10.obs;
@override @override
void onInit() { void onInit() {
@ -22,6 +24,8 @@ class SettingController extends GetxController {
userLogin.value = user.get(UserBoxKey.userLogin) ?? false; userLogin.value = user.get(UserBoxKey.userLogin) ?? false;
feedBackEnable.value = feedBackEnable.value =
setting.get(SettingBoxKey.feedBackEnable, defaultValue: false); setting.get(SettingBoxKey.feedBackEnable, defaultValue: false);
picQuality.value =
setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10);
} }
loginOut() async { loginOut() async {

View File

@ -31,13 +31,19 @@ class _PlaySettingState extends State<PlaySetting> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
TextStyle titleStyle = Theme.of(context).textTheme.titleMedium!;
TextStyle subTitleStyle = Theme.of(context) TextStyle subTitleStyle = Theme.of(context)
.textTheme .textTheme
.labelMedium! .labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline); .copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('播放设置'), centerTitle: false,
titleSpacing: 0,
title: Text(
'播放设置',
style: Theme.of(context).textTheme.titleMedium,
),
), ),
body: ListView( body: ListView(
children: [ children: [
@ -45,15 +51,17 @@ class _PlaySettingState extends State<PlaySetting> {
title: '自动播放', title: '自动播放',
subTitle: '进入详情页自动播放', subTitle: '进入详情页自动播放',
setKey: SettingBoxKey.autoPlayEnable, setKey: SettingBoxKey.autoPlayEnable,
defaultVal: true,
), ),
const SetSwitchItem( const SetSwitchItem(
title: '开启硬解', title: '开启硬解',
subTitle: '以较低功耗播放视频', subTitle: '以较低功耗播放视频',
setKey: SettingBoxKey.enableHA, setKey: SettingBoxKey.enableHA,
defaultVal: true,
), ),
ListTile( ListTile(
dense: false, dense: false,
title: const Text('默认画质'), title: Text('默认画质', style: titleStyle),
subtitle: Text( subtitle: Text(
'当前画质' + VideoQualityCode.fromCode(defaultVideoQa)!.description!, '当前画质' + VideoQualityCode.fromCode(defaultVideoQa)!.description!,
style: subTitleStyle, style: subTitleStyle,
@ -78,7 +86,7 @@ class _PlaySettingState extends State<PlaySetting> {
), ),
ListTile( ListTile(
dense: false, dense: false,
title: const Text('默认音质'), title: Text('默认音质', style: titleStyle),
subtitle: Text( subtitle: Text(
'当前音质' + AudioQualityCode.fromCode(defaultAudioQa)!.description!, '当前音质' + AudioQualityCode.fromCode(defaultAudioQa)!.description!,
style: subTitleStyle, style: subTitleStyle,
@ -103,7 +111,7 @@ class _PlaySettingState extends State<PlaySetting> {
), ),
ListTile( ListTile(
dense: false, dense: false,
title: const Text('默认解码格式'), title: Text('默认解码格式', style: titleStyle),
subtitle: Text( subtitle: Text(
'当前解码格式' + '当前解码格式' +
VideoDecodeFormatsCode.fromCode(defaultDecode)!.description!, VideoDecodeFormatsCode.fromCode(defaultDecode)!.description!,

View File

@ -0,0 +1,127 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/utils/storage.dart';
import 'controller.dart';
class StyleSetting extends StatefulWidget {
const StyleSetting({super.key});
@override
State<StyleSetting> createState() => _StyleSettingState();
}
class _StyleSettingState extends State<StyleSetting> {
final SettingController settingController = Get.put(SettingController());
Box setting = GStrorage.setting;
late int picQuality;
@override
void initState() {
super.initState();
picQuality = setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10);
}
@override
Widget build(BuildContext context) {
TextStyle titleStyle = Theme.of(context).textTheme.titleMedium!;
TextStyle subTitleStyle = Theme.of(context)
.textTheme
.labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold(
appBar: AppBar(
centerTitle: false,
titleSpacing: 0,
title: Text(
'外观设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: ListView(
children: [
Obx(
() => ListTile(
enableFeedback: true,
onTap: () => settingController.onOpenFeedBack(),
title: const Text('震动反馈'),
subtitle: Text('请确定手机设置中已开启震动反馈', style: subTitleStyle),
trailing: Transform.scale(
scale: 0.8,
child: Switch(
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
(Set<MaterialState> states) {
if (states.isNotEmpty &&
states.first == MaterialState.selected) {
return const Icon(Icons.done);
}
return null; // All other states will use the default thumbIcon.
}),
value: settingController.feedBackEnable.value,
onChanged: (value) => settingController.onOpenFeedBack()),
),
),
),
ListTile(
dense: false,
onTap: () {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, StateSetter setState) {
final SettingController settingController =
Get.put(SettingController());
return AlertDialog(
title: Text('图片清晰度 - $picQuality%', style: titleStyle),
contentPadding: const EdgeInsets.only(
top: 20, left: 8, right: 8, bottom: 8),
content: SizedBox(
height: 40,
child: Slider(
value: picQuality.toDouble(),
min: 10,
max: 100,
divisions: 9,
label: '$picQuality%',
onChanged: (double val) {
picQuality = val.toInt();
setState(() {});
},
),
),
actions: [
TextButton(
onPressed: () => Get.back(),
child: const Text('取消')),
TextButton(
onPressed: () {
setting.put(
SettingBoxKey.defaultPicQa, picQuality);
Get.back();
settingController.picQuality.value = picQuality;
},
child: const Text('确定'),
)
],
);
},
);
},
);
},
title: Text('图片质量', style: titleStyle),
subtitle: Text('选择合适的图片清晰度上限100%', style: subTitleStyle),
trailing: Obx(
() => Text(
'${settingController.picQuality.value}%',
style: Theme.of(context).textTheme.titleSmall,
),
),
),
],
),
);
}
}

View File

@ -14,42 +14,25 @@ class SettingPage extends StatelessWidget {
final SettingController settingController = Get.put(SettingController()); final SettingController settingController = Get.put(SettingController());
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('设置'), centerTitle: false,
titleSpacing: 0,
title: Text(
'设置',
style: Theme.of(context).textTheme.titleMedium,
),
), ),
body: Column( body: Column(
children: [ children: [
Obx(
() => ListTile(
enableFeedback: true,
onTap: () => settingController.onOpenFeedBack(),
title: const Text('震动反馈'),
subtitle: Text('请确定手机设置中已开启震动反馈', style: subTitleStyle),
trailing: Transform.scale(
scale: 0.8,
child: Switch(
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
(Set<MaterialState> states) {
if (states.isNotEmpty &&
states.first == MaterialState.selected) {
return const Icon(Icons.done);
}
return null; // All other states will use the default thumbIcon.
}),
value: settingController.feedBackEnable.value,
onChanged: (value) => settingController.onOpenFeedBack()),
),
),
),
ListTile( ListTile(
onTap: () => Get.toNamed('/playSetting'), onTap: () => Get.toNamed('/playSetting'),
dense: false, dense: false,
title: const Text('播放设置'), title: const Text('播放设置'),
), ),
// ListTile( ListTile(
// onTap: () {}, onTap: () => Get.toNamed('/styleSetting'),
// dense: false, dense: false,
// title: const Text('外观设置'), title: const Text('外观设置'),
// ), ),
// ListTile( // ListTile(
// onTap: () {}, // onTap: () {},
// dense: false, // dense: false,

View File

@ -6,11 +6,13 @@ class SetSwitchItem extends StatefulWidget {
final String? title; final String? title;
final String? subTitle; final String? subTitle;
final String? setKey; final String? setKey;
final bool? defaultVal;
const SetSwitchItem({ const SetSwitchItem({
this.title, this.title,
this.subTitle, this.subTitle,
this.setKey, this.setKey,
this.defaultVal,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -26,11 +28,12 @@ class _SetSwitchItemState extends State<SetSwitchItem> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
val = Setting.get(widget.setKey, defaultValue: false); val = Setting.get(widget.setKey, defaultValue: widget.defaultVal ?? false);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
TextStyle titleStyle = Theme.of(context).textTheme.titleMedium!;
TextStyle subTitleStyle = Theme.of(context) TextStyle subTitleStyle = Theme.of(context)
.textTheme .textTheme
.labelMedium! .labelMedium!
@ -40,7 +43,7 @@ class _SetSwitchItemState extends State<SetSwitchItem> {
onTap: () { onTap: () {
Setting.put(widget.setKey, !val); Setting.put(widget.setKey, !val);
}, },
title: Text(widget.title!), title: Text(widget.title!, style: titleStyle),
subtitle: widget.subTitle != null subtitle: widget.subTitle != null
? Text(widget.subTitle!, style: subTitleStyle) ? Text(widget.subTitle!, style: subTitleStyle)
: null, : null,

View File

@ -15,6 +15,7 @@ import 'package:pilipala/pages/preview/index.dart';
import 'package:pilipala/pages/search/index.dart'; import 'package:pilipala/pages/search/index.dart';
import 'package:pilipala/pages/searchResult/index.dart'; import 'package:pilipala/pages/searchResult/index.dart';
import 'package:pilipala/pages/setting/play_setting.dart'; import 'package:pilipala/pages/setting/play_setting.dart';
import 'package:pilipala/pages/setting/style_setting.dart';
import 'package:pilipala/pages/video/detail/index.dart'; import 'package:pilipala/pages/video/detail/index.dart';
import 'package:pilipala/pages/video/detail/replyReply/index.dart'; import 'package:pilipala/pages/video/detail/replyReply/index.dart';
import 'package:pilipala/pages/webview/index.dart'; import 'package:pilipala/pages/webview/index.dart';
@ -71,6 +72,8 @@ class Routes {
GetPage(name: '/replyReply', page: () => const VideoReplyReplyPanel()), GetPage(name: '/replyReply', page: () => const VideoReplyReplyPanel()),
// 播放设置 // 播放设置
GetPage(name: '/playSetting', page: () => const PlaySetting()) GetPage(name: '/playSetting', page: () => const PlaySetting()),
GetPage(name: '/styleSetting', page: () => const StyleSetting()),
]; ];
} }

View File

@ -76,6 +76,7 @@ class SettingBoxKey {
static const String autoUpgradeEnable = 'autoUpgradeEnable'; static const String autoUpgradeEnable = 'autoUpgradeEnable';
static const String autoPlayEnable = 'autoPlayEnable'; static const String autoPlayEnable = 'autoPlayEnable';
static const String enableHA = 'enableHA'; static const String enableHA = 'enableHA';
static const String defaultPicQa = 'defaultPicQa';
static const String danmakuEnable = 'danmakuEnable'; static const String danmakuEnable = 'danmakuEnable';
} }