mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-23 20:10:12 +08:00
@@ -17,8 +17,8 @@ class MsgFeedTopSkeleton extends StatelessWidget {
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
title: UnconstrainedBox(
|
||||
alignment: Alignment.centerLeft,
|
||||
title: Align(
|
||||
alignment: .topLeft,
|
||||
child: Container(
|
||||
width: 100,
|
||||
height: 11,
|
||||
|
||||
@@ -17,8 +17,8 @@ class WhisperItemSkeleton extends StatelessWidget {
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
title: UnconstrainedBox(
|
||||
alignment: Alignment.centerLeft,
|
||||
title: Align(
|
||||
alignment: .topLeft,
|
||||
child: Container(
|
||||
width: 100,
|
||||
height: 11,
|
||||
|
||||
@@ -39,6 +39,7 @@ class LiveCardVApp extends StatelessWidget {
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
child: Column(
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
@@ -56,11 +57,7 @@ class LiveCardVApp extends StatelessWidget {
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: AnimatedOpacity(
|
||||
opacity: 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: videoStat(),
|
||||
),
|
||||
child: videoStat(),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -159,7 +156,6 @@ class LiveCardVApp extends StatelessWidget {
|
||||
|
||||
Widget liveContent(ThemeData theme) {
|
||||
return Expanded(
|
||||
flex: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(5, 8, 5, 4),
|
||||
child: Column(
|
||||
@@ -173,18 +169,15 @@ class LiveCardVApp extends StatelessWidget {
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Align(
|
||||
alignment: .topLeft,
|
||||
child: Text(
|
||||
item.uname.toString(),
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
Text(
|
||||
item.uname.toString(),
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -28,6 +28,7 @@ class LiveCardVFollow extends StatelessWidget {
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
child: Column(
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
@@ -48,11 +49,7 @@ class LiveCardVFollow extends StatelessWidget {
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: AnimatedOpacity(
|
||||
opacity: 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: videoStat(context),
|
||||
),
|
||||
child: videoStat(),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -69,7 +66,6 @@ class LiveCardVFollow extends StatelessWidget {
|
||||
Widget liveContent(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Expanded(
|
||||
flex: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(5, 8, 5, 4),
|
||||
child: Column(
|
||||
@@ -77,7 +73,7 @@ class LiveCardVFollow extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'${liveItem.title}',
|
||||
liveItem.title.toString(),
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
letterSpacing: 0.3,
|
||||
@@ -85,21 +81,15 @@ class LiveCardVFollow extends StatelessWidget {
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${liveItem.uname}',
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
Text(
|
||||
liveItem.uname.toString(),
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -107,7 +97,7 @@ class LiveCardVFollow extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget videoStat(BuildContext context) {
|
||||
Widget videoStat() {
|
||||
return Container(
|
||||
height: 50,
|
||||
padding: const EdgeInsets.only(top: 26, left: 10, right: 10),
|
||||
@@ -126,7 +116,7 @@ class LiveCardVFollow extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'${liveItem.areaName}',
|
||||
liveItem.areaName.toString(),
|
||||
style: const TextStyle(fontSize: 11, color: Colors.white),
|
||||
),
|
||||
if (liveItem.textSmall case final textSmall?)
|
||||
|
||||
@@ -28,7 +28,7 @@ class LiveCardVSearch extends StatelessWidget {
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
@@ -49,11 +49,7 @@ class LiveCardVSearch extends StatelessWidget {
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: AnimatedOpacity(
|
||||
opacity: 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: videoStat(context),
|
||||
),
|
||||
child: videoStat(),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -63,7 +59,7 @@ class LiveCardVSearch extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(5, 8, 5, 4),
|
||||
child: Text(
|
||||
'${item.title}',
|
||||
item.title.toString(),
|
||||
textAlign: TextAlign.start,
|
||||
style: const TextStyle(
|
||||
letterSpacing: 0.3,
|
||||
@@ -78,7 +74,7 @@ class LiveCardVSearch extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget videoStat(BuildContext context) {
|
||||
Widget videoStat() {
|
||||
return Container(
|
||||
height: 50,
|
||||
padding: const EdgeInsets.only(top: 26, left: 10, right: 10),
|
||||
@@ -97,7 +93,7 @@ class LiveCardVSearch extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'${item.name}',
|
||||
item.name.toString(),
|
||||
style: const TextStyle(fontSize: 11, color: Colors.white),
|
||||
),
|
||||
if (item.watchedShow?.textLarge case final textLarge?)
|
||||
|
||||
@@ -26,7 +26,7 @@ class LiveItem extends StatelessWidget {
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
@@ -47,13 +47,9 @@ class LiveItem extends StatelessWidget {
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: AnimatedOpacity(
|
||||
opacity: 1,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: liveStat(
|
||||
liveItem.online,
|
||||
liveItem.cateName,
|
||||
),
|
||||
child: liveStat(
|
||||
liveItem.online,
|
||||
liveItem.cateName,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -25,44 +25,47 @@ class AiConclusionPanel extends CommonSlidePage {
|
||||
Key? key,
|
||||
bool tap = true,
|
||||
}) {
|
||||
return CustomScrollView(
|
||||
key: key,
|
||||
shrinkWrap: !tap,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
if (res.summary?.isNotEmpty == true) ...[
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14),
|
||||
child: SelectableText(
|
||||
res.summary!,
|
||||
style: const TextStyle(fontSize: 15, height: 1.5),
|
||||
scrollPhysics: const NeverScrollableScrollPhysics(),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (res.outline?.isNotEmpty == true)
|
||||
final outline = res.outline;
|
||||
final hasOutline = outline != null && outline.isNotEmpty;
|
||||
return SelectionArea(
|
||||
child: CustomScrollView(
|
||||
key: key,
|
||||
shrinkWrap: !tap,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
if (res.summary?.isNotEmpty == true) ...[
|
||||
SliverToBoxAdapter(
|
||||
child: Divider(
|
||||
height: 20,
|
||||
color: theme.dividerColor.withValues(alpha: 0.1),
|
||||
thickness: 6,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 14),
|
||||
child: Text(
|
||||
res.summary!,
|
||||
style: const TextStyle(fontSize: 15, height: 1.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (res.outline?.isNotEmpty == true)
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 14,
|
||||
right: 14,
|
||||
bottom: !tap ? 0 : MediaQuery.viewPaddingOf(context).bottom + 100,
|
||||
),
|
||||
sliver: SliverList.builder(
|
||||
itemCount: res.outline!.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = res.outline![index];
|
||||
return SelectionArea(
|
||||
child: Column(
|
||||
if (hasOutline)
|
||||
SliverToBoxAdapter(
|
||||
child: Divider(
|
||||
height: 20,
|
||||
color: theme.dividerColor.withValues(alpha: 0.1),
|
||||
thickness: 6,
|
||||
),
|
||||
),
|
||||
],
|
||||
if (hasOutline)
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 14,
|
||||
right: 14,
|
||||
bottom: !tap
|
||||
? 0
|
||||
: MediaQuery.viewPaddingOf(context).bottom + 100,
|
||||
),
|
||||
sliver: SliverList.builder(
|
||||
itemCount: outline.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = outline[index];
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (index != 0) const SizedBox(height: 10),
|
||||
@@ -120,12 +123,12 @@ class AiConclusionPanel extends CommonSlidePage {
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,7 +1305,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
bool showIntro = true,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
List<String> tabs = [
|
||||
final tabs = [
|
||||
if (showIntro)
|
||||
videoDetailController.isFileSource ? '离线视频' : introText ?? '简介',
|
||||
if (videoDetailController.showReply) '评论',
|
||||
@@ -1322,53 +1322,61 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
);
|
||||
}
|
||||
|
||||
final flag = !needIndicator || tabs.length == 1;
|
||||
Widget tabBar() => TabBar(
|
||||
labelColor: flag ? themeData.colorScheme.onSurface : null,
|
||||
indicator: flag ? const BoxDecoration() : null,
|
||||
padding: EdgeInsets.zero,
|
||||
controller: videoDetailController.tabCtr,
|
||||
labelStyle:
|
||||
TabBarTheme.of(context).labelStyle?.copyWith(fontSize: 13) ??
|
||||
const TextStyle(fontSize: 13),
|
||||
labelPadding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
dividerColor: Colors.transparent,
|
||||
dividerHeight: 0,
|
||||
onTap: (value) {
|
||||
void animToTop() {
|
||||
if (onTap != null) {
|
||||
onTap();
|
||||
return;
|
||||
Widget tabBar() {
|
||||
final flag = !needIndicator || tabs.length == 1;
|
||||
return TabBar(
|
||||
padding: .zero,
|
||||
dividerHeight: 0,
|
||||
labelPadding: .zero,
|
||||
dividerColor: Colors.transparent,
|
||||
controller: videoDetailController.tabCtr,
|
||||
indicator: flag ? const BoxDecoration() : null,
|
||||
labelColor: flag ? themeData.colorScheme.onSurface : null,
|
||||
labelStyle:
|
||||
TabBarTheme.of(context).labelStyle?.copyWith(fontSize: 13) ??
|
||||
const TextStyle(fontSize: 13),
|
||||
onTap: (value) {
|
||||
void animToTop() {
|
||||
if (onTap != null) {
|
||||
onTap();
|
||||
return;
|
||||
}
|
||||
String text = tabs[value];
|
||||
if (videoDetailController.isFileSource ||
|
||||
text == '简介' ||
|
||||
text == '相关视频') {
|
||||
videoDetailController.introScrollCtr?.animToTop();
|
||||
} else if (text.startsWith('评论')) {
|
||||
_videoReplyController.animateToTop();
|
||||
}
|
||||
}
|
||||
String text = tabs[value];
|
||||
if (videoDetailController.isFileSource ||
|
||||
text == '简介' ||
|
||||
text == '相关视频') {
|
||||
videoDetailController.introScrollCtr?.animToTop();
|
||||
} else if (text.startsWith('评论')) {
|
||||
_videoReplyController.animateToTop();
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
animToTop();
|
||||
} else if (!videoDetailController.tabCtr.indexIsChanging) {
|
||||
animToTop();
|
||||
}
|
||||
},
|
||||
tabs: tabs.map((text) {
|
||||
if (text == '评论') {
|
||||
return Obx(() {
|
||||
final count = _videoReplyController.count.value;
|
||||
if (flag) {
|
||||
animToTop();
|
||||
} else if (!videoDetailController.tabCtr.indexIsChanging) {
|
||||
animToTop();
|
||||
}
|
||||
},
|
||||
tabs: tabs.map((text) {
|
||||
if (text == '评论') {
|
||||
return Obx(() {
|
||||
final count = _videoReplyController.count.value;
|
||||
return Tab(
|
||||
child: Text(
|
||||
'评论${count == -1 ? '' : ' ${NumUtils.numFormat(count)}'}',
|
||||
softWrap: false,
|
||||
overflow: .visible,
|
||||
),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return Tab(
|
||||
text: '评论${count == -1 ? '' : ' ${NumUtils.numFormat(count)}'}',
|
||||
child: Text(text, softWrap: false, overflow: .visible),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return Tab(text: text);
|
||||
}
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
@@ -1385,68 +1393,62 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
if (tabs.isEmpty)
|
||||
const Spacer()
|
||||
else
|
||||
Flexible(
|
||||
flex: tabs.length == 3 ? 2 : 1,
|
||||
child: tabBar(),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: .centerLeft,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: 96.0 * tabs.length),
|
||||
child: tabBar(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 32,
|
||||
child: TextButton(
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: videoDetailController.showShootDanmakuSheet,
|
||||
child: Text(
|
||||
'发弹幕',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: themeData.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 38,
|
||||
height: 38,
|
||||
child: Obx(
|
||||
() {
|
||||
final ctr = videoDetailController.plPlayerController;
|
||||
final enableShowDanmaku = ctr.enableShowDanmaku.value;
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
ctr.enableShowDanmaku.value = newVal;
|
||||
if (!ctr.tempPlayerConf) {
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
size: 22,
|
||||
enableShowDanmaku
|
||||
? CustomIcons.dm_on
|
||||
: CustomIcons.dm_off,
|
||||
color: enableShowDanmaku
|
||||
? themeData.colorScheme.secondary
|
||||
: themeData.colorScheme.outline,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
],
|
||||
SizedBox(
|
||||
height: 32,
|
||||
child: TextButton(
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(.zero),
|
||||
),
|
||||
onPressed: videoDetailController.showShootDanmakuSheet,
|
||||
child: Text(
|
||||
'发弹幕',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: themeData.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox.square(
|
||||
dimension: 38,
|
||||
child: Obx(
|
||||
() {
|
||||
final ctr = videoDetailController.plPlayerController;
|
||||
final enableShowDanmaku = ctr.enableShowDanmaku.value;
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
ctr.enableShowDanmaku.value = newVal;
|
||||
if (!ctr.tempPlayerConf) {
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
size: 22,
|
||||
enableShowDanmaku
|
||||
? CustomIcons.dm_on
|
||||
: CustomIcons.dm_off,
|
||||
color: enableShowDanmaku
|
||||
? themeData.colorScheme.secondary
|
||||
: themeData.colorScheme.outline,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 14),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1330,14 +1330,14 @@ class HeaderControlState extends State<HeaderControl>
|
||||
|
||||
void updateFontScaleFS(double val) {
|
||||
plPlayerController
|
||||
..subtitleFontScaleFS = val
|
||||
..subtitleFontScaleFS = val.toPrecision(2)
|
||||
..updateSubtitleStyle();
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void updateFontScale(double val) {
|
||||
plPlayerController
|
||||
..subtitleFontScale = val
|
||||
..subtitleFontScale = val.toPrecision(2)
|
||||
..updateSubtitleStyle();
|
||||
setState(() {});
|
||||
}
|
||||
@@ -1387,7 +1387,7 @@ class HeaderControlState extends State<HeaderControl>
|
||||
min: 0.5,
|
||||
max: 2.5,
|
||||
value: subtitleFontScale,
|
||||
divisions: 20,
|
||||
divisions: 200,
|
||||
label:
|
||||
'${(subtitleFontScale * 100).toStringAsFixed(1)}%',
|
||||
onChanged: updateFontScale,
|
||||
@@ -1416,7 +1416,7 @@ class HeaderControlState extends State<HeaderControl>
|
||||
min: 0.5,
|
||||
max: 2.5,
|
||||
value: subtitleFontScaleFS,
|
||||
divisions: 20,
|
||||
divisions: 200,
|
||||
label:
|
||||
'${(subtitleFontScaleFS * 100).toStringAsFixed(1)}%',
|
||||
onChanged: updateFontScaleFS,
|
||||
@@ -1530,7 +1530,9 @@ class HeaderControlState extends State<HeaderControl>
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('背景不透明度 ${(subtitleBgOpacity * 100).toInt()}%'),
|
||||
Text(
|
||||
'背景不透明度 ${(subtitleBgOpacity * 100).toStringAsFixed(1)}%',
|
||||
),
|
||||
resetBtn(theme, '67%', () => updateOpacity(0.67)),
|
||||
],
|
||||
),
|
||||
@@ -1546,6 +1548,7 @@ class HeaderControlState extends State<HeaderControl>
|
||||
child: Slider(
|
||||
min: 0,
|
||||
max: 1,
|
||||
divisions: 100,
|
||||
value: subtitleBgOpacity,
|
||||
onChanged: updateOpacity,
|
||||
),
|
||||
|
||||
@@ -108,7 +108,7 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
|
||||
}
|
||||
|
||||
void updateFontSizeFS(double val) {
|
||||
DanmakuOptions.danmakuFontScaleFS = val;
|
||||
DanmakuOptions.danmakuFontScaleFS = val.toPrecision(2);
|
||||
setState(() {});
|
||||
if (isFullScreen) {
|
||||
setOptions();
|
||||
@@ -116,7 +116,7 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
|
||||
}
|
||||
|
||||
void updateFontSize(double val) {
|
||||
DanmakuOptions.danmakuFontScale = val;
|
||||
DanmakuOptions.danmakuFontScale = val.toPrecision(2);
|
||||
setState(() {});
|
||||
if (!isFullScreen) {
|
||||
setOptions();
|
||||
@@ -136,7 +136,7 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
|
||||
}
|
||||
|
||||
void updateOpacity(double val) {
|
||||
plPlayerController.danmakuOpacity.value = val;
|
||||
plPlayerController.danmakuOpacity.value = val.toPrecision(2);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@@ -286,7 +286,9 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('显示区域 ${DanmakuOptions.danmakuShowArea * 100}%'),
|
||||
Text(
|
||||
'显示区域 ${(DanmakuOptions.danmakuShowArea * 100).toStringAsFixed(1)}%',
|
||||
),
|
||||
resetBtn(theme, '50.0%', () => updateShowArea(0.5)),
|
||||
],
|
||||
),
|
||||
@@ -312,7 +314,9 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('不透明度 ${plPlayerController.danmakuOpacity * 100}%'),
|
||||
Text(
|
||||
'不透明度 ${(plPlayerController.danmakuOpacity * 100).toStringAsFixed(1)}%',
|
||||
),
|
||||
resetBtn(theme, '100.0%', () => updateOpacity(1.0)),
|
||||
],
|
||||
),
|
||||
@@ -330,7 +334,8 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
|
||||
max: 1,
|
||||
value: plPlayerController.danmakuOpacity.value,
|
||||
divisions: 100,
|
||||
label: '${plPlayerController.danmakuOpacity * 100}%',
|
||||
label:
|
||||
'${(plPlayerController.danmakuOpacity * 100).toStringAsFixed(1)}%',
|
||||
onChanged: updateOpacity,
|
||||
),
|
||||
),
|
||||
@@ -384,8 +389,7 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
|
||||
max: 5,
|
||||
value: DanmakuOptions.danmakuStrokeWidth,
|
||||
divisions: 10,
|
||||
label: DanmakuOptions.danmakuStrokeWidth
|
||||
.toStringAsFixed(0),
|
||||
label: DanmakuOptions.danmakuStrokeWidth.toString(),
|
||||
onChanged: updateStrokeWidth,
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user