opt: get theme color

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-04-28 21:32:30 +08:00
parent 451a84e696
commit ca993df0c6
149 changed files with 4415 additions and 4803 deletions

View File

@@ -128,79 +128,76 @@ class _VideoInfoState extends State<VideoInfo> {
late final _horizontalMemberPage = GStorage.horizontalMemberPage;
Widget _buildVideoTitle([bool isExpand = false]) => videoDetailCtr
.enableSponsorBlock
? Obx(
() => Text.rich(
TextSpan(
children: [
if (videoDetailCtr.videoLabel.value.isNotEmpty) ...[
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 2,
),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.secondaryContainer,
borderRadius: BorderRadius.circular(4),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
alignment: Alignment.center,
Widget _buildVideoTitle(ThemeData theme, [bool isExpand = false]) =>
videoDetailCtr.enableSponsorBlock
? Obx(
() => Text.rich(
TextSpan(
children: [
if (videoDetailCtr.videoLabel.value.isNotEmpty) ...[
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 2,
),
decoration: BoxDecoration(
color: theme.colorScheme.secondaryContainer,
borderRadius: BorderRadius.circular(4),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.shield_outlined,
size: 16,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
Stack(
alignment: Alignment.center,
children: [
Icon(
Icons.shield_outlined,
size: 16,
color:
theme.colorScheme.onSecondaryContainer,
),
Icon(
Icons.play_arrow_rounded,
size: 12,
color:
theme.colorScheme.onSecondaryContainer,
),
],
),
Icon(
Icons.play_arrow_rounded,
size: 12,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
Text(
videoDetailCtr.videoLabel.value,
textScaler: TextScaler.linear(1),
strutStyle: StrutStyle(leading: 0, height: 1),
style: TextStyle(
height: 1,
fontSize: 13,
color: theme.colorScheme.onSecondaryContainer,
),
),
],
),
Text(
videoDetailCtr.videoLabel.value,
textScaler: TextScaler.linear(1),
strutStyle: StrutStyle(leading: 0, height: 1),
style: TextStyle(
height: 1,
fontSize: 13,
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
),
),
],
),
),
),
),
TextSpan(text: ' '),
],
TextSpan(
text: '${videoDetail.title ?? videoItem['title'] ?? ''}'),
],
),
maxLines: isExpand ? null : 2,
overflow: isExpand ? null : TextOverflow.ellipsis,
style: const TextStyle(fontSize: 16),
),
)
: Text(
'${videoDetail.title ?? videoItem['title'] ?? ''}',
maxLines: isExpand ? null : 2,
overflow: isExpand ? null : TextOverflow.ellipsis,
style: const TextStyle(fontSize: 16),
);
TextSpan(text: ' '),
],
TextSpan(
text:
'${videoDetail.title ?? videoItem['title'] ?? ''}'),
],
),
maxLines: isExpand ? null : 2,
overflow: isExpand ? null : TextOverflow.ellipsis,
style: const TextStyle(fontSize: 16),
),
)
: Text(
'${videoDetail.title ?? videoItem['title'] ?? ''}',
maxLines: isExpand ? null : 2,
overflow: isExpand ? null : TextOverflow.ellipsis,
style: const TextStyle(fontSize: 16),
);
void handleState(Future Function() action) async {
if (isProcessing.not) {
@@ -263,7 +260,7 @@ class _VideoInfoState extends State<VideoInfo> {
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final ThemeData theme = Theme.of(context);
return SliverLayoutBuilder(
builder: (BuildContext context, SliverConstraints constraints) {
bool isHorizontal = context.orientation == Orientation.landscape &&
@@ -350,8 +347,7 @@ class _VideoInfoState extends State<VideoInfo> {
'${Utils.numFormat(videoIntroController.userStat['follower'])}粉丝 ${videoIntroController.userStat['archive_count'] != null ? '${Utils.numFormat(videoIntroController.userStat['archive_count'])}视频' : ''}',
style: TextStyle(
fontSize: 12,
color:
themeData.colorScheme.outline,
color: theme.colorScheme.outline,
),
),
),
@@ -362,7 +358,7 @@ class _VideoInfoState extends State<VideoInfo> {
),
),
),
followButton(context, themeData),
followButton(context, theme),
] else
Expanded(
child: SelfSizedHorizontalList(
@@ -409,9 +405,8 @@ class _VideoInfoState extends State<VideoInfo> {
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context)
.colorScheme
.surface,
color:
theme.colorScheme.surface,
),
child: Icon(
Icons.offline_bolt,
@@ -461,16 +456,14 @@ class _VideoInfoState extends State<VideoInfo> {
const EdgeInsets.all(
2),
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
color: theme.colorScheme
.secondaryContainer,
shape: BoxShape.circle,
),
child: Icon(
MdiIcons.plus,
size: 16,
color: Theme.of(context)
.colorScheme
color: theme.colorScheme
.onSecondaryContainer,
),
),
@@ -508,9 +501,7 @@ class _VideoInfoState extends State<VideoInfo> {
videoItem['staff'][index].title,
style: TextStyle(
fontSize: 12,
color: Theme.of(context)
.colorScheme
.outline,
color: theme.colorScheme.outline,
),
),
],
@@ -537,7 +528,7 @@ class _VideoInfoState extends State<VideoInfo> {
Utils.copyText(
'${videoDetail.title ?? videoItem['title'] ?? ''}');
},
child: _buildVideoTitle(),
child: _buildVideoTitle(theme),
),
expanded: GestureDetector(
onLongPress: () {
@@ -545,7 +536,7 @@ class _VideoInfoState extends State<VideoInfo> {
Utils.copyText(
'${videoDetail.title ?? videoItem['title'] ?? ''}');
},
child: _buildVideoTitle(true),
child: _buildVideoTitle(theme, true),
),
theme: const ExpandableThemeData(
animationDuration: Duration(milliseconds: 300),
@@ -566,7 +557,7 @@ class _VideoInfoState extends State<VideoInfo> {
value: Utils.numFormat(!widget.loadingStatus
? videoDetail.stat?.view ?? '-'
: videoItem['stat']?.view ?? '-'),
textColor: themeData.colorScheme.outline,
textColor: theme.colorScheme.outline,
),
const SizedBox(width: 10),
StatDanMu(
@@ -575,7 +566,7 @@ class _VideoInfoState extends State<VideoInfo> {
value: Utils.numFormat(!widget.loadingStatus
? videoDetail.stat?.danmaku ?? '-'
: videoItem['stat']?.danmu ?? '-'),
textColor: themeData.colorScheme.outline,
textColor: theme.colorScheme.outline,
),
const SizedBox(width: 10),
Text(
@@ -586,7 +577,7 @@ class _VideoInfoState extends State<VideoInfo> {
formatType: 'detail'),
style: TextStyle(
fontSize: 12,
color: themeData.colorScheme.outline,
color: theme.colorScheme.outline,
),
),
if (MineController.anonymity.value) ...<Widget>[
@@ -594,7 +585,7 @@ class _VideoInfoState extends State<VideoInfo> {
Icon(
MdiIcons.incognito,
size: 15,
color: themeData.colorScheme.outline,
color: theme.colorScheme.outline,
semanticLabel: '无痕',
),
],
@@ -605,7 +596,7 @@ class _VideoInfoState extends State<VideoInfo> {
'${videoIntroController.total.value}人在看',
style: TextStyle(
fontSize: 12,
color: themeData.colorScheme.outline,
color: theme.colorScheme.outline,
),
),
),
@@ -656,7 +647,7 @@ class _VideoInfoState extends State<VideoInfo> {
child: Icon(
size: 13,
Icons.error_outline,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
WidgetSpan(child: SizedBox(width: 2)),
@@ -668,7 +659,7 @@ class _VideoInfoState extends State<VideoInfo> {
),
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
],
@@ -689,7 +680,7 @@ class _VideoInfoState extends State<VideoInfo> {
videoIntroController.videoDetail.value.bvid ?? '',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
),
),
@@ -702,7 +693,7 @@ class _VideoInfoState extends State<VideoInfo> {
),
TextSpan(
children: [
buildContent(context,
buildContent(theme,
videoIntroController.videoDetail.value),
],
),
@@ -1013,7 +1004,7 @@ class _VideoInfoState extends State<VideoInfo> {
]);
}
InlineSpan buildContent(BuildContext context, VideoDetailData content) {
InlineSpan buildContent(ThemeData theme, VideoDetailData content) {
final List descV2 = content.descV2!;
// type
// 1 普通文本
@@ -1039,8 +1030,7 @@ class _VideoInfoState extends State<VideoInfo> {
spanChildren.add(
TextSpan(
text: matchStr,
style: TextStyle(
color: Theme.of(context).colorScheme.primary),
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
..onTap = () {
PiliScheme.videoPush(aid, null);
@@ -1057,8 +1047,7 @@ class _VideoInfoState extends State<VideoInfo> {
spanChildren.add(
TextSpan(
text: matchStr,
style: TextStyle(
color: Theme.of(context).colorScheme.primary),
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
..onTap = () {
PiliScheme.videoPush(null, matchStr);
@@ -1072,8 +1061,7 @@ class _VideoInfoState extends State<VideoInfo> {
spanChildren.add(
TextSpan(
text: matchStr,
style:
TextStyle(color: Theme.of(context).colorScheme.primary),
style: TextStyle(color: theme.colorScheme.primary),
recognizer: TapGestureRecognizer()
..onTap = () {
try {
@@ -1094,8 +1082,7 @@ class _VideoInfoState extends State<VideoInfo> {
);
return TextSpan(children: spanChildren);
case 2:
final Color colorSchemePrimary =
Theme.of(context).colorScheme.primary;
final Color colorSchemePrimary = theme.colorScheme.primary;
final String heroTag = Utils.makeHeroTag(currentDesc.bizId);
return TextSpan(
text: '@${currentDesc.rawText}',

View File

@@ -127,10 +127,13 @@ class ActionItemState extends State<ActionItem>
@override
Widget build(BuildContext context) {
return widget.expand == false ? _buildItem : Expanded(child: _buildItem);
final theme = Theme.of(context);
return widget.expand == false
? _buildItem(theme)
: Expanded(child: _buildItem(theme));
}
Widget get _buildItem => Semantics(
Widget _buildItem(ThemeData theme) => Semantics(
label: (widget.text ?? "") +
(widget.selectStatus ? "" : "") +
widget.semanticsLabel,
@@ -160,7 +163,7 @@ class ActionItemState extends State<ActionItem>
CustomPaint(
size: const Size(28, 28),
painter: _ArcPainter(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
sweepAngle: _animation!.value,
),
)
@@ -172,9 +175,8 @@ class ActionItemState extends State<ActionItem>
: widget.icon.icon,
size: 18,
color: widget.selectStatus
? Theme.of(context).colorScheme.primary
: widget.icon.color ??
Theme.of(context).colorScheme.outline,
? theme.colorScheme.primary
: widget.icon.color ?? theme.colorScheme.outline,
),
],
),
@@ -193,10 +195,9 @@ class ActionItemState extends State<ActionItem>
key: ValueKey<String>(widget.text!),
style: TextStyle(
color: widget.selectStatus
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.outline,
fontSize:
Theme.of(context).textTheme.labelSmall!.fontSize,
? theme.colorScheme.primary
: theme.colorScheme.outline,
fontSize: theme.textTheme.labelSmall!.fontSize,
),
semanticsLabel: "",
),

View File

@@ -23,10 +23,11 @@ class ActionRowItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Material(
color: selectStatus
? Theme.of(context).colorScheme.primaryContainer.withOpacity(0.6)
: Theme.of(context).highlightColor.withOpacity(0.2),
? theme.colorScheme.primaryContainer.withOpacity(0.6)
: theme.highlightColor.withOpacity(0.2),
borderRadius: const BorderRadius.all(Radius.circular(30)),
clipBehavior: Clip.hardEdge,
child: InkWell(
@@ -47,8 +48,8 @@ class ActionRowItem extends StatelessWidget {
Icon(icon!.icon!,
size: 13,
color: selectStatus
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSecondaryContainer),
? theme.colorScheme.primary
: theme.colorScheme.onSecondaryContainer),
const SizedBox(width: 6),
],
AnimatedOpacity(
@@ -64,11 +65,8 @@ class ActionRowItem extends StatelessWidget {
text ?? '',
key: ValueKey<String>(text ?? ''),
style: TextStyle(
color: selectStatus
? Theme.of(context).colorScheme.primary
: null,
fontSize:
Theme.of(context).textTheme.labelMedium!.fontSize),
color: selectStatus ? theme.colorScheme.primary : null,
fontSize: theme.textTheme.labelMedium!.fontSize),
),
),
),

View File

@@ -61,6 +61,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: Text(_mediaId != null ? '编辑' : '创建'),
@@ -94,7 +95,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
),
body: _mediaId != null
? _titleController.text.isNotEmpty
? _buildBody
? _buildBody(theme)
: _errMsg?.isNotEmpty == true
? Center(
child: CustomScrollView(
@@ -108,11 +109,11 @@ class _CreateFavPageState extends State<CreateFavPage> {
),
)
: Center(child: CircularProgressIndicator())
: _buildBody,
: _buildBody(theme),
);
}
void _pickImg() async {
void _pickImg(ThemeData theme) async {
try {
XFile? pickedFile = await _imagePicker.pickImage(
source: ImageSource.gallery,
@@ -124,9 +125,8 @@ class _CreateFavPageState extends State<CreateFavPage> {
uiSettings: [
AndroidUiSettings(
toolbarTitle: '裁剪',
toolbarColor: Theme.of(context).colorScheme.secondaryContainer,
toolbarWidgetColor:
Theme.of(context).colorScheme.onSecondaryContainer,
toolbarColor: theme.colorScheme.secondaryContainer,
toolbarWidgetColor: theme.colorScheme.onSecondaryContainer,
aspectRatioPresets: [
CropAspectRatioPreset.ratio16x9,
],
@@ -167,12 +167,12 @@ class _CreateFavPageState extends State<CreateFavPage> {
dynamic leadingStyle = TextStyle(fontSize: 14);
Widget get _buildBody => SingleChildScrollView(
Widget _buildBody(ThemeData theme) => SingleChildScrollView(
child: Column(
children: [
if (_attr == null || !Utils.isDefaultFav(_attr!)) ...[
ListTile(
tileColor: Theme.of(context).colorScheme.onInverseSurface,
tileColor: theme.colorScheme.onInverseSurface,
onTap: () {
EasyThrottle.throttle(
'imagePicker', const Duration(milliseconds: 500),
@@ -192,7 +192,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
dense: true,
onTap: () {
Get.back();
_pickImg();
_pickImg(theme);
},
title: const Text(
'替换封面',
@@ -217,7 +217,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
},
);
} else {
_pickImg();
_pickImg(theme);
}
});
},
@@ -248,7 +248,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
const SizedBox(width: 10),
Icon(
Icons.keyboard_arrow_right,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
],
),
@@ -256,7 +256,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
const SizedBox(height: 16),
],
ListTile(
tileColor: Theme.of(context).colorScheme.onInverseSurface,
tileColor: theme.colorScheme.onInverseSurface,
leading: Text.rich(
style: TextStyle(
height: 1,
@@ -269,7 +269,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
style: TextStyle(
fontSize: 14,
height: 1,
color: Theme.of(context).colorScheme.error,
color: theme.colorScheme.error,
),
),
TextSpan(
@@ -289,7 +289,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
style: TextStyle(
fontSize: 14,
color: _attr != null && Utils.isDefaultFav(_attr!)
? Theme.of(context).colorScheme.outline
? theme.colorScheme.outline
: null,
),
inputFormatters: [
@@ -300,7 +300,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
hintText: '名称',
hintStyle: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
@@ -313,7 +313,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
const SizedBox(height: 16),
if (_attr == null || !Utils.isDefaultFav(_attr!)) ...[
ListTile(
tileColor: Theme.of(context).colorScheme.onInverseSurface,
tileColor: theme.colorScheme.onInverseSurface,
title: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -324,9 +324,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
text: '简介',
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
color: theme.colorScheme.onSurfaceVariant,
),
),
TextSpan(
@@ -351,7 +349,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
hintText: '可填写简介',
hintStyle: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
border: OutlineInputBorder(
borderSide: BorderSide.none,
@@ -372,7 +370,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
_isPublic = !_isPublic;
});
},
tileColor: Theme.of(context).colorScheme.onInverseSurface,
tileColor: theme.colorScheme.onInverseSurface,
leading: Text(
'公开',
style: leadingStyle,

View File

@@ -31,6 +31,7 @@ class _FavPanelState extends State<FavPanel> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return NotificationListener<DraggableScrollableNotification>(
onNotification: (notification) {
if (notification.extent <= 1e-5) {
@@ -62,7 +63,7 @@ class _FavPanelState extends State<FavPanel> {
},
icon: Icon(
Icons.add,
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
label: const Text('新建收藏夹'),
style: TextButton.styleFrom(
@@ -156,7 +157,7 @@ class _FavPanelState extends State<FavPanel> {
),
Divider(
height: 1,
color: Theme.of(context).disabledColor.withOpacity(0.08),
color: theme.disabledColor.withOpacity(0.08),
),
Padding(
padding: EdgeInsets.only(
@@ -177,9 +178,8 @@ class _FavPanelState extends State<FavPanel> {
horizontal: -1,
vertical: -2,
),
foregroundColor: Theme.of(context).colorScheme.outline,
backgroundColor:
Theme.of(context).colorScheme.onInverseSurface,
foregroundColor: theme.colorScheme.outline,
backgroundColor: theme.colorScheme.onInverseSurface,
),
child: const Text('取消'),
),

View File

@@ -68,6 +68,7 @@ class _GroupPanelState extends State<GroupPanel> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return NotificationListener<DraggableScrollableNotification>(
onNotification: (notification) {
if (notification.extent <= 1e-5) {
@@ -159,7 +160,7 @@ class _GroupPanelState extends State<GroupPanel> {
),
Divider(
height: 1,
color: Theme.of(context).disabledColor.withOpacity(0.08),
color: theme.disabledColor.withOpacity(0.08),
),
Padding(
padding: EdgeInsets.only(
@@ -175,8 +176,8 @@ class _GroupPanelState extends State<GroupPanel> {
onPressed: () => onSave(),
style: TextButton.styleFrom(
padding: const EdgeInsets.only(left: 30, right: 30),
foregroundColor: Theme.of(context).colorScheme.onPrimary,
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: theme.colorScheme.onPrimary,
backgroundColor: theme.colorScheme.primary,
),
child: Text(showDefaultBtn ? '保存至默认分组' : '保存'),
),

View File

@@ -10,9 +10,10 @@ class MenuRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Container(
width: double.infinity,
color: Theme.of(context).colorScheme.surface,
color: theme.colorScheme.surface,
padding: const EdgeInsets.only(top: 9, bottom: 9, left: 12),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
@@ -50,11 +51,11 @@ class MenuRow extends StatelessWidget {
}
Widget actionRowLineItem(
BuildContext context, Function? onTap, bool? loadingStatus, String? text,
ThemeData theme, Function? onTap, bool? loadingStatus, String? text,
{bool selectStatus = false}) {
return Material(
color: selectStatus
? Theme.of(context).highlightColor.withOpacity(0.2)
? theme.highlightColor.withOpacity(0.2)
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(30)),
clipBehavior: Clip.hardEdge,
@@ -70,7 +71,7 @@ class MenuRow extends StatelessWidget {
border: Border.all(
color: selectStatus
? Colors.transparent
: Theme.of(context).highlightColor.withOpacity(0.2),
: theme.highlightColor.withOpacity(0.2),
),
),
child: Row(
@@ -84,8 +85,8 @@ class MenuRow extends StatelessWidget {
style: TextStyle(
fontSize: 13,
color: selectStatus
? Theme.of(context).colorScheme.onSurface
: Theme.of(context).colorScheme.outline),
? theme.colorScheme.onSurface
: theme.colorScheme.outline),
),
),
],
@@ -115,9 +116,10 @@ class ActionRowLineItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Material(
color: selectStatus
? Theme.of(context).colorScheme.secondaryContainer
? theme.colorScheme.secondaryContainer
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(30)),
clipBehavior: Clip.hardEdge,
@@ -133,7 +135,7 @@ class ActionRowLineItem extends StatelessWidget {
border: Border.all(
color: selectStatus
? Colors.transparent
: Theme.of(context).colorScheme.secondaryContainer,
: theme.colorScheme.secondaryContainer,
),
),
child: Row(
@@ -144,8 +146,8 @@ class ActionRowLineItem extends StatelessWidget {
iconData,
size: 13,
color: selectStatus
? Theme.of(context).colorScheme.onSecondaryContainer
: Theme.of(context).colorScheme.outline,
? theme.colorScheme.onSecondaryContainer
: theme.colorScheme.outline,
)
else if (icon != null)
icon!,
@@ -157,8 +159,8 @@ class ActionRowLineItem extends StatelessWidget {
style: TextStyle(
fontSize: 13,
color: selectStatus
? Theme.of(context).colorScheme.onSecondaryContainer
: Theme.of(context).colorScheme.outline),
? theme.colorScheme.onSecondaryContainer
: theme.colorScheme.outline),
),
),
],

View File

@@ -87,6 +87,7 @@ class _PagesPanelState extends State<PagesPanel> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Column(
children: <Widget>[
if (widget.showEpisodes != null)
@@ -102,7 +103,7 @@ class _PagesPanelState extends State<PagesPanel> {
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
),
@@ -145,7 +146,7 @@ class _PagesPanelState extends State<PagesPanel> {
right: i != pages.length - 1 ? 10 : 0,
),
child: Material(
color: Theme.of(context).colorScheme.onInverseSurface,
color: theme.colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(6),
clipBehavior: Clip.hardEdge,
child: InkWell(
@@ -175,7 +176,7 @@ class _PagesPanelState extends State<PagesPanel> {
if (isCurrentIndex) ...<Widget>[
Image.asset(
'assets/images/live.png',
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
height: 12,
semanticLabel: "正在播放:",
),
@@ -188,8 +189,8 @@ class _PagesPanelState extends State<PagesPanel> {
style: TextStyle(
fontSize: 13,
color: isCurrentIndex
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSurface,
? theme.colorScheme.primary
: theme.colorScheme.onSurface,
),
overflow: TextOverflow.ellipsis,
))

View File

@@ -88,6 +88,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
if (episodes.isEmpty) {
return const SizedBox.shrink();
}
final theme = Theme.of(context);
return Builder(builder: (BuildContext context) {
return Container(
margin: const EdgeInsets.only(
@@ -96,7 +97,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
right: 2,
),
child: Material(
color: Theme.of(context).colorScheme.onInverseSurface,
color: theme.colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(6),
clipBehavior: Clip.hardEdge,
child: InkWell(
@@ -117,14 +118,14 @@ class _SeasonPanelState extends State<SeasonPanel> {
Expanded(
child: Text(
'合集:${videoDetail.ugcSeason!.title!}',
style: Theme.of(context).textTheme.labelMedium,
style: theme.textTheme.labelMedium,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(width: 15),
Image.asset(
'assets/images/live.png',
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
height: 12,
semanticLabel: "正在播放:",
),
@@ -132,7 +133,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
Obx(
() => Text(
'${currentIndex.value + 1}/${episodes.length}',
style: Theme.of(context).textTheme.labelMedium,
style: theme.textTheme.labelMedium,
semanticsLabel:
'${currentIndex.value + 1}集,共${episodes.length}',
),

View File

@@ -78,12 +78,13 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Obx(
() => _buildUserPage(_controller.userState.value),
() => _buildUserPage(theme, _controller.userState.value),
);
}
Widget _buildUserPage(LoadingState userState) {
Widget _buildUserPage(ThemeData theme, LoadingState userState) {
return switch (userState) {
Loading() => loadingWidget,
Success() => Column(
@@ -102,10 +103,11 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
const SizedBox(width: 16),
],
),
_buildUserInfo(userState.response),
_buildUserInfo(theme, userState.response),
const SizedBox(height: 5),
Expanded(
child: Obx(() => _buildVideoList(_controller.loadingState.value)),
child: Obx(
() => _buildVideoList(theme, _controller.loadingState.value)),
),
],
),
@@ -120,13 +122,13 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
};
}
Widget get _buildSliverHeader {
Widget _buildSliverHeader(ThemeData theme) {
return SliverPersistentHeader(
pinned: false,
floating: true,
delegate: CustomSliverPersistentHeaderDelegate(
extent: 40,
bgColor: Theme.of(context).colorScheme.surface,
bgColor: theme.colorScheme.surface,
child: Container(
height: 40,
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
@@ -153,14 +155,14 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
icon: Icon(
Icons.sort,
size: 16,
color: Theme.of(context).colorScheme.secondary,
color: theme.colorScheme.secondary,
),
label: Obx(
() => Text(
_controller.order.value == 'pubdate' ? '最新发布' : '最多播放',
style: TextStyle(
fontSize: 13,
color: Theme.of(context).colorScheme.secondary,
color: theme.colorScheme.secondary,
),
),
),
@@ -173,7 +175,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
);
}
Widget _buildVideoList(LoadingState loadingState) {
Widget _buildVideoList(ThemeData theme, LoadingState loadingState) {
return switch (loadingState) {
Loading() => loadingWidget,
Success() => Material(
@@ -185,7 +187,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
parent: ClampingScrollPhysics(),
),
slivers: [
_buildSliverHeader,
_buildSliverHeader(theme),
SliverPadding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom + 80,
@@ -234,19 +236,19 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
};
}
Widget _buildUserInfo(MemberInfoModel memberInfoModel) {
Widget _buildUserInfo(ThemeData theme, MemberInfoModel memberInfoModel) {
return Row(
children: [
const SizedBox(width: 16),
_buildAvatar(memberInfoModel.face),
const SizedBox(width: 10),
Expanded(child: _buildInfo(memberInfoModel)),
Expanded(child: _buildInfo(theme, memberInfoModel)),
const SizedBox(width: 16),
],
);
}
_buildInfo(MemberInfoModel memberInfoModel) => Column(
_buildInfo(ThemeData theme, MemberInfoModel memberInfoModel) => Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -281,6 +283,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
children: List.generate(5, (index) {
if (index % 2 == 0) {
return _buildChildInfo(
theme: theme,
title: const ['粉丝', '关注', '获赞'][index ~/ 2],
num: index == 0
? _controller.userStat['follower'] != null
@@ -307,7 +310,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
width: 20,
child: VerticalDivider(
width: 1,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
);
}
@@ -321,10 +324,10 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
child: FilledButton.tonal(
style: FilledButton.styleFrom(
backgroundColor: memberInfoModel.isFollowed == true
? Theme.of(context).colorScheme.onInverseSurface
? theme.colorScheme.onInverseSurface
: null,
foregroundColor: memberInfoModel.isFollowed == true
? Theme.of(context).colorScheme.outline
? theme.colorScheme.outline
: null,
padding: const EdgeInsets.all(0),
visualDensity: const VisualDensity(
@@ -389,6 +392,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
);
Widget _buildChildInfo({
required ThemeData theme,
required String title,
required dynamic num,
required VoidCallback onTap,
@@ -399,7 +403,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
'$num$title',
style: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
);

View File

@@ -50,87 +50,91 @@ class _NoteListPageState extends CommonSlidePageState<NoteListPage> {
}
@override
Widget get buildPage => Scaffold(
key: _key,
Widget buildPage(ThemeData theme) {
return Scaffold(
key: _key,
resizeToAvoidBottomInset: false,
body: Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: false,
body: Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: false,
appBar: AppBar(
automaticallyImplyLeading: false,
titleSpacing: 16,
toolbarHeight: 45,
title: Obx(
() => Text(
'笔记${_controller.count.value == -1 ? '' : '(${_controller.count.value})'}'),
),
bottom: PreferredSize(
preferredSize: Size.fromHeight(1),
child: Divider(
height: 1,
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
),
),
actions: [
iconButton(
context: context,
tooltip: '关闭',
icon: Icons.clear,
onPressed: Get.back,
size: 32,
),
const SizedBox(width: 16),
],
appBar: AppBar(
automaticallyImplyLeading: false,
titleSpacing: 16,
toolbarHeight: 45,
title: Obx(
() => Text(
'笔记${_controller.count.value == -1 ? '' : '(${_controller.count.value})'}'),
),
body: enableSlide
? slideList(Obx(() => _buildBody(_controller.loadingState.value)))
: Obx(() => _buildBody(_controller.loadingState.value)),
bottomNavigationBar: Container(
padding: EdgeInsets.only(
left: 12,
right: 12,
top: 6,
bottom: MediaQuery.paddingOf(context).bottom + 6,
bottom: PreferredSize(
preferredSize: Size.fromHeight(1),
child: Divider(
height: 1,
color: theme.colorScheme.outline.withOpacity(0.1),
),
width: double.infinity,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.onInverseSurface,
border: Border(
top: BorderSide(
width: 0.5,
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
),
),
actions: [
iconButton(
context: context,
tooltip: '关闭',
icon: Icons.clear,
onPressed: Get.back,
size: 32,
),
const SizedBox(width: 16),
],
),
body: enableSlide
? slideList(theme,
Obx(() => _buildBody(theme, _controller.loadingState.value)))
: Obx(() => _buildBody(theme, _controller.loadingState.value)),
bottomNavigationBar: Container(
padding: EdgeInsets.only(
left: 12,
right: 12,
top: 6,
bottom: MediaQuery.paddingOf(context).bottom + 6,
),
width: double.infinity,
decoration: BoxDecoration(
color: theme.colorScheme.onInverseSurface,
border: Border(
top: BorderSide(
width: 0.5,
color: theme.colorScheme.outline.withOpacity(0.1),
),
),
child: FilledButton.tonal(
style: FilledButton.styleFrom(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
child: FilledButton.tonal(
style: FilledButton.styleFrom(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
onPressed: () {
if (!Accounts.main.isLogin) {
SmartDialog.showToast('账号未登录');
return;
}
_key.currentState?.showBottomSheet(
(context) => WebviewPageNew(
oid: widget.oid,
title: widget.title,
url:
'https://www.bilibili.com/h5/note-app?oid=${widget.oid}&pagefrom=ugcvideo&is_stein_gate=${widget.isStein ? 1 : 0}',
),
);
},
child: const Text('开始记笔记'),
),
onPressed: () {
if (!Accounts.main.isLogin) {
SmartDialog.showToast('账号未登录');
return;
}
_key.currentState?.showBottomSheet(
(context) => WebviewPageNew(
oid: widget.oid,
title: widget.title,
url:
'https://www.bilibili.com/h5/note-app?oid=${widget.oid}&pagefrom=ugcvideo&is_stein_gate=${widget.isStein ? 1 : 0}',
),
);
},
child: const Text('开始记笔记'),
),
),
);
),
);
}
Widget _buildBody(LoadingState<List<dynamic>?> loadingState) {
Widget _buildBody(
ThemeData theme, LoadingState<List<dynamic>?> loadingState) {
return switch (loadingState) {
Loading() => CustomScrollView(
physics: const NeverScrollableScrollPhysics(),
@@ -158,15 +162,12 @@ class _NoteListPageState extends CommonSlidePageState<NoteListPage> {
_controller.onLoadMore();
}
return _itemWidget(
context, loadingState.response![index]);
context, theme, loadingState.response![index]);
},
itemCount: loadingState.response!.length,
separatorBuilder: (context, index) => Divider(
height: 1,
color: Theme.of(context)
.colorScheme
.outline
.withOpacity(0.1),
color: theme.colorScheme.outline.withOpacity(0.1),
),
),
SliverToBoxAdapter(
@@ -193,7 +194,7 @@ class _NoteListPageState extends CommonSlidePageState<NoteListPage> {
);
}
Widget _itemWidget(BuildContext context, dynamic item) {
Widget _itemWidget(BuildContext context, ThemeData theme, dynamic item) {
return InkWell(
onTap: () {
if (item['web_url'] != null && item['web_url'] != '') {
@@ -235,7 +236,7 @@ Widget _itemWidget(BuildContext context, dynamic item) {
0 &&
item['author']?['vip_info']?['type'] == 2
? context.vipColor
: Theme.of(context).colorScheme.outline,
: theme.colorScheme.outline,
fontSize: 13,
),
),
@@ -251,7 +252,7 @@ Widget _itemWidget(BuildContext context, dynamic item) {
Text(
item['pubtime'],
style: TextStyle(
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
fontSize: 12,
),
),
@@ -261,18 +262,16 @@ Widget _itemWidget(BuildContext context, dynamic item) {
item['summary'],
style: TextStyle(
height: 1.75,
fontSize:
Theme.of(context).textTheme.bodyMedium!.fontSize,
fontSize: theme.textTheme.bodyMedium!.fontSize,
),
),
if (item['web_url'] != null && item['web_url'] != '')
Text(
'查看全部',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
height: 1.75,
fontSize:
Theme.of(context).textTheme.bodyMedium!.fontSize,
fontSize: theme.textTheme.bodyMedium!.fontSize,
),
),
],

View File

@@ -50,352 +50,363 @@ class _PostPanelState extends CommonCollapseSlidePageState<PostPanel> {
plPlayerController.position.value.inMilliseconds / 1000;
@override
Widget get buildPage => Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
automaticallyImplyLeading: false,
titleSpacing: 16,
title: const Text('提交片段'),
actions: [
iconButton(
context: context,
tooltip: '添加片段',
onPressed: () {
setState(() {
list?.insert(
0,
PostSegmentModel(
segment: Pair(
first: 0,
second: currentPos,
),
category: SegmentType.sponsor,
actionType: ActionType.skip,
Widget buildPage(ThemeData theme) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
automaticallyImplyLeading: false,
titleSpacing: 16,
title: const Text('提交片段'),
actions: [
iconButton(
context: context,
tooltip: '添加片段',
onPressed: () {
setState(() {
list?.insert(
0,
PostSegmentModel(
segment: Pair(
first: 0,
second: currentPos,
),
);
});
},
icon: Icons.add,
),
const SizedBox(width: 10),
iconButton(
context: context,
tooltip: '关闭',
onPressed: Get.back,
icon: Icons.close,
),
const SizedBox(width: 16),
],
),
body: enableSlide ? slideList() : buildList,
);
category: SegmentType.sponsor,
actionType: ActionType.skip,
),
);
});
},
icon: Icons.add,
),
const SizedBox(width: 10),
iconButton(
context: context,
tooltip: '关闭',
onPressed: Get.back,
icon: Icons.close,
),
const SizedBox(width: 16),
],
),
body: enableSlide ? slideList(theme) : buildList(theme),
);
}
@override
Widget get buildList => list?.isNotEmpty == true
? Stack(
children: [
SingleChildScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
...List.generate(
list!.length,
(index) => Stack(
clipBehavior: Clip.none,
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 5,
),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color:
Theme.of(context).colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (list![index].actionType !=
ActionType.full) ...[
Widget buildList(ThemeData theme) {
return list?.isNotEmpty == true
? Stack(
children: [
SingleChildScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
...List.generate(
list!.length,
(index) => Stack(
clipBehavior: Clip.none,
children: [
Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 5,
),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: theme.colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (list![index].actionType !=
ActionType.full) ...[
Wrap(
runSpacing: 8,
spacing: 16,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: segmentWidget(
theme,
isFirst: true,
index: index,
),
),
if (list![index].category !=
SegmentType.poi_highlight)
Row(
mainAxisSize: MainAxisSize.min,
children: segmentWidget(
theme,
isFirst: false,
index: index,
),
),
],
),
const SizedBox(height: 8),
],
Wrap(
runSpacing: 8,
spacing: 16,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: segmentWidget(
isFirst: true,
index: index,
),
),
if (list![index].category !=
SegmentType.poi_highlight)
Row(
mainAxisSize: MainAxisSize.min,
children: segmentWidget(
isFirst: false,
index: index,
children: [
const Text('分类: '),
PopupMenuButton<SegmentType>(
initialValue: list![index].category,
onSelected: (item) async {
list![index].category = item;
List<ActionType> constraintList =
segmentType2ActionType(item);
if (constraintList
.contains(
list![index].actionType)
.not) {
list![index].actionType =
constraintList.first;
}
switch (item) {
case SegmentType.poi_highlight:
updateSegment(
isFirst: false,
index: index,
value: list![index]
.segment
.first,
);
break;
case SegmentType.exclusive_access:
updateSegment(
isFirst: true,
index: index,
value: 0,
);
break;
case _:
}
setState(() {});
},
itemBuilder: (context) => SegmentType
.values
.map((item) =>
PopupMenuItem<SegmentType>(
value: item,
child: Text(item.title),
))
.toList(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
list![index].category.title,
style: TextStyle(
height: 1,
fontSize: 14,
color: theme
.colorScheme.secondary,
),
strutStyle: StrutStyle(
height: 1,
leading: 0,
),
),
Icon(
MdiIcons.unfoldMoreHorizontal,
size: MediaQuery.textScalerOf(
context)
.scale(14),
color:
theme.colorScheme.secondary,
),
],
),
),
),
],
),
const SizedBox(height: 8),
],
Wrap(
runSpacing: 8,
spacing: 16,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('分类: '),
PopupMenuButton<SegmentType>(
initialValue: list![index].category,
onSelected: (item) async {
list![index].category = item;
List<ActionType> constraintList =
segmentType2ActionType(item);
if (constraintList
.contains(list![index].actionType)
.not) {
list![index].actionType =
constraintList.first;
}
switch (item) {
case SegmentType.poi_highlight:
updateSegment(
isFirst: false,
index: index,
value:
list![index].segment.first,
);
break;
case SegmentType.exclusive_access:
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('行为类别: '),
PopupMenuButton<ActionType>(
initialValue: list![index].actionType,
onSelected: (item) async {
list![index].actionType = item;
if (item == ActionType.full) {
updateSegment(
isFirst: true,
index: index,
value: 0,
);
break;
case _:
}
setState(() {});
},
itemBuilder: (context) => SegmentType
.values
.map((item) =>
PopupMenuItem<SegmentType>(
}
setState(() {});
},
itemBuilder: (context) => ActionType
.values
.map(
(item) =>
PopupMenuItem<ActionType>(
enabled:
segmentType2ActionType(
list![index]
.category)
.contains(item),
value: item,
child: Text(item.title),
))
.toList(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
list![index].category.title,
style: TextStyle(
height: 1,
fontSize: 14,
color: Theme.of(context)
.colorScheme
.secondary,
),
)
.toList(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
list![index].actionType.title,
style: TextStyle(
height: 1,
fontSize: 14,
color: theme
.colorScheme.secondary,
),
strutStyle: StrutStyle(
height: 1,
leading: 0,
),
),
strutStyle: StrutStyle(
height: 1,
leading: 0,
Icon(
MdiIcons.unfoldMoreHorizontal,
size: MediaQuery.textScalerOf(
context)
.scale(14),
color:
theme.colorScheme.secondary,
),
),
Icon(
MdiIcons.unfoldMoreHorizontal,
size: MediaQuery.textScalerOf(
context)
.scale(14),
color: Theme.of(context)
.colorScheme
.secondary,
),
],
],
),
),
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('行为类别: '),
PopupMenuButton<ActionType>(
initialValue: list![index].actionType,
onSelected: (item) async {
list![index].actionType = item;
if (item == ActionType.full) {
updateSegment(
isFirst: true,
index: index,
value: 0,
);
}
setState(() {});
},
itemBuilder: (context) => ActionType
.values
.map(
(item) =>
PopupMenuItem<ActionType>(
enabled: segmentType2ActionType(
list![index].category)
.contains(item),
value: item,
child: Text(item.title),
),
)
.toList(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
list![index].actionType.title,
style: TextStyle(
height: 1,
fontSize: 14,
color: Theme.of(context)
.colorScheme
.secondary,
),
strutStyle: StrutStyle(
height: 1,
leading: 0,
),
),
Icon(
MdiIcons.unfoldMoreHorizontal,
size: MediaQuery.textScalerOf(
context)
.scale(14),
color: Theme.of(context)
.colorScheme
.secondary,
),
],
),
),
],
),
],
),
],
),
),
Positioned(
top: 0,
right: 4,
child: iconButton(
context: context,
size: 26,
tooltip: '移除',
icon: Icons.clear,
onPressed: () {
setState(() {
list!.removeAt(index);
});
},
),
),
Positioned(
top: 0,
left: 4,
child: iconButton(
context: context,
size: 26,
tooltip: '预览',
icon: Icons.preview_outlined,
onPressed: () async {
if (widget.plPlayerController
.videoPlayerController !=
null) {
int start = max(
0,
(list![index].segment.first * 1000).toInt() -
1,
);
await widget
.plPlayerController.videoPlayerController!
.seek(
Duration(milliseconds: start),
);
if (widget.plPlayerController
.videoPlayerController!.state.playing.not) {
await widget
.plPlayerController.videoPlayerController!
.play();
}
if (start != 0) {
await Future.delayed(
const Duration(seconds: 1));
}
widget.plPlayerController.videoPlayerController!
.seek(
Duration(
milliseconds:
(list![index].segment.second * 1000)
.toInt(),
),
);
}
},
),
),
],
),
),
SizedBox(
height: 88 + MediaQuery.paddingOf(context).bottom,
),
],
),
),
Positioned(
right: 16,
bottom: 16 + MediaQuery.paddingOf(context).bottom,
child: FloatingActionButton(
tooltip: '提交',
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('确定无误再提交'),
actions: [
TextButton(
onPressed: Get.back,
child: Text(
'取消',
style: TextStyle(
color: Theme.of(context).colorScheme.outline,
],
),
],
),
],
),
),
),
TextButton(
onPressed: () {
Get.back();
_onPost();
},
child: const Text('确定提交'),
),
],
Positioned(
top: 0,
right: 4,
child: iconButton(
context: context,
size: 26,
tooltip: '移除',
icon: Icons.clear,
onPressed: () {
setState(() {
list!.removeAt(index);
});
},
),
),
Positioned(
top: 0,
left: 4,
child: iconButton(
context: context,
size: 26,
tooltip: '预览',
icon: Icons.preview_outlined,
onPressed: () async {
if (widget.plPlayerController
.videoPlayerController !=
null) {
int start = max(
0,
(list![index].segment.first * 1000)
.toInt() -
1,
);
await widget
.plPlayerController.videoPlayerController!
.seek(
Duration(milliseconds: start),
);
if (widget
.plPlayerController
.videoPlayerController!
.state
.playing
.not) {
await widget.plPlayerController
.videoPlayerController!
.play();
}
if (start != 0) {
await Future.delayed(
const Duration(seconds: 1));
}
widget
.plPlayerController.videoPlayerController!
.seek(
Duration(
milliseconds:
(list![index].segment.second * 1000)
.toInt(),
),
);
}
},
),
),
],
),
),
);
},
child: Icon(Icons.check),
SizedBox(
height: 88 + MediaQuery.paddingOf(context).bottom,
),
],
),
),
)
],
)
: errorWidget();
Positioned(
right: 16,
bottom: 16 + MediaQuery.paddingOf(context).bottom,
child: FloatingActionButton(
tooltip: '提交',
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('确定无误再提交'),
actions: [
TextButton(
onPressed: Get.back,
child: Text(
'取消',
style: TextStyle(
color: theme.colorScheme.outline,
),
),
),
TextButton(
onPressed: () {
Get.back();
_onPost();
},
child: const Text('确定提交'),
),
],
),
);
},
child: Icon(Icons.check),
),
)
],
)
: errorWidget();
}
void updateSegment({
required bool isFirst,
@@ -413,7 +424,8 @@ class _PostPanelState extends CommonCollapseSlidePageState<PostPanel> {
}
}
List<Widget> segmentWidget({
List<Widget> segmentWidget(
ThemeData theme, {
required int index,
required bool isFirst,
}) {
@@ -484,8 +496,7 @@ class _PostPanelState extends CommonCollapseSlidePageState<PostPanel> {
onPressed: Get.back,
child: Text(
'取消',
style: TextStyle(
color: Theme.of(context).colorScheme.outline),
style: TextStyle(color: theme.colorScheme.outline),
),
),
TextButton(

View File

@@ -98,6 +98,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
@override
Widget build(BuildContext context) {
super.build(context);
final theme = Theme.of(context);
return refreshIndicator(
onRefresh: () async {
await _videoReplyController.onRefresh();
@@ -120,7 +121,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
floating: true,
delegate: CustomSliverPersistentHeaderDelegate(
extent: 40,
bgColor: Theme.of(context).colorScheme.surface,
bgColor: theme.colorScheme.surface,
child: Container(
height: 40,
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
@@ -141,15 +142,14 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
icon: Icon(
Icons.sort,
size: 16,
color: Theme.of(context).colorScheme.secondary,
color: theme.colorScheme.secondary,
),
label: Obx(
() => Text(
_videoReplyController.sortType.value.label,
style: TextStyle(
fontSize: 13,
color:
Theme.of(context).colorScheme.secondary,
color: theme.colorScheme.secondary,
),
),
),
@@ -160,7 +160,8 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
),
),
),
Obx(() => _buildBody(_videoReplyController.loadingState.value)),
Obx(() =>
_buildBody(theme, _videoReplyController.loadingState.value)),
],
),
Positioned(
@@ -194,7 +195,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
);
}
Widget _buildBody(LoadingState loadingState) {
Widget _buildBody(ThemeData theme, LoadingState loadingState) {
return switch (loadingState) {
Loading() => SliverList.builder(
itemBuilder: (BuildContext context, index) {
@@ -220,7 +221,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
: '没有更多了',
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
);

View File

@@ -62,6 +62,7 @@ class ReplyItemGrpc extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return Material(
color: Colors.transparent,
child: InkWell(
@@ -90,17 +91,17 @@ class ReplyItemGrpc extends StatelessWidget {
},
);
},
child: _buildContent(context),
child: _buildContent(context, theme),
),
);
}
Widget _buildAuthorPanel(context) => Padding(
Widget _buildAuthorPanel(BuildContext context, ThemeData theme) => Padding(
padding: const EdgeInsets.fromLTRB(12, 14, 8, 5),
child: content(context),
child: content(context, theme),
);
Widget _buildContent(context) {
Widget _buildContent(BuildContext context, ThemeData theme) {
return Column(
children: [
if (Avatar.showDynDecorate && replyItem.member.hasGarbCardImage())
@@ -138,18 +139,18 @@ class ReplyItemGrpc extends StatelessWidget {
),
SizedBox(
width: double.infinity,
child: _buildAuthorPanel(context),
child: _buildAuthorPanel(context, theme),
),
],
)
else
_buildAuthorPanel(context),
_buildAuthorPanel(context, theme),
if (needDivider)
Divider(
indent: 55,
endIndent: 15,
height: 0.3,
color: Theme.of(context).colorScheme.outline.withOpacity(0.08),
color: theme.colorScheme.outline.withOpacity(0.08),
)
],
);
@@ -166,7 +167,7 @@ class ReplyItemGrpc extends StatelessWidget {
: null,
);
Widget content(BuildContext context) {
Widget content(BuildContext context, ThemeData theme) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
@@ -196,7 +197,7 @@ class ReplyItemGrpc extends StatelessWidget {
color: (replyItem.member.vipStatus > 0 &&
replyItem.member.vipType == 2)
? context.vipColor
: Theme.of(context).colorScheme.outline,
: theme.colorScheme.outline,
fontSize: 13,
),
),
@@ -227,20 +228,16 @@ class ReplyItemGrpc extends StatelessWidget {
.substring(0, 19)
: Utils.dateFormat(replyItem.ctime.toInt()),
style: TextStyle(
fontSize:
Theme.of(context).textTheme.labelSmall!.fontSize,
color: Theme.of(context).colorScheme.outline,
fontSize: theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline,
),
),
if (replyItem.replyControl.location.isNotEmpty)
Text(
'${replyItem.replyControl.location}',
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.labelSmall!
.fontSize,
color: Theme.of(context).colorScheme.outline),
fontSize: theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline),
),
],
)
@@ -262,7 +259,7 @@ class ReplyItemGrpc extends StatelessWidget {
String text = replyItem.content.message;
TextStyle style = TextStyle(
height: 1.75,
fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize,
fontSize: theme.textTheme.bodyMedium!.fontSize,
);
TextPainter? textPainter;
bool? didExceedMaxLines;
@@ -297,8 +294,8 @@ class ReplyItemGrpc extends StatelessWidget {
],
buildContent(
context,
theme,
replyItem,
replyReply,
null,
textPainter,
didExceedMaxLines,
@@ -311,16 +308,15 @@ class ReplyItemGrpc extends StatelessWidget {
),
),
// 操作区域
if (replyLevel != '') buttonAction(context, replyItem.replyControl),
if (replyLevel != '')
buttonAction(context, theme, replyItem.replyControl),
// 一楼的评论
if (replyLevel == '1' &&
(replyItem.replies.isNotEmpty ||
replyItem.replyControl.subReplyEntryText.isNotEmpty)) ...[
Padding(
padding: const EdgeInsets.only(top: 5, bottom: 12),
child: replyItemRow(
context: context,
),
child: replyItemRow(context, theme),
),
],
],
@@ -334,7 +330,8 @@ class ReplyItemGrpc extends StatelessWidget {
);
// 感谢、回复、复制
Widget buttonAction(BuildContext context, replyControl) {
Widget buttonAction(
BuildContext context, ThemeData theme, ReplyControl replyControl) {
return Row(
children: <Widget>[
const SizedBox(width: 36),
@@ -350,14 +347,14 @@ class ReplyItemGrpc extends StatelessWidget {
Icon(
Icons.reply,
size: 18,
color: Theme.of(context).colorScheme.outline.withOpacity(0.8),
color: theme.colorScheme.outline.withOpacity(0.8),
),
const SizedBox(width: 3),
Text(
'回复',
style: TextStyle(
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
color: Theme.of(context).colorScheme.outline,
fontSize: theme.textTheme.labelMedium!.fontSize,
color: theme.colorScheme.outline,
),
),
]),
@@ -373,8 +370,8 @@ class ReplyItemGrpc extends StatelessWidget {
child: Text(
'UP主觉得很赞',
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
color: theme.colorScheme.secondary,
fontSize: theme.textTheme.labelMedium!.fontSize,
fontWeight: FontWeight.normal,
),
),
@@ -389,8 +386,8 @@ class ReplyItemGrpc extends StatelessWidget {
Text(
'热评',
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize),
color: theme.colorScheme.secondary,
fontSize: theme.textTheme.labelMedium!.fontSize),
),
if (replyLevel == '2' &&
needDivider &&
@@ -403,8 +400,8 @@ class ReplyItemGrpc extends StatelessWidget {
child: Text(
'查看对话',
style: TextStyle(
color: Theme.of(context).colorScheme.outline,
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
color: theme.colorScheme.outline,
fontSize: theme.textTheme.labelMedium!.fontSize,
fontWeight: FontWeight.normal,
),
),
@@ -417,12 +414,12 @@ class ReplyItemGrpc extends StatelessWidget {
);
}
Widget replyItemRow({required BuildContext context}) {
Widget replyItemRow(BuildContext context, ThemeData theme) {
final bool extraRow = replyItem.replies.length < replyItem.count.toInt();
return Container(
margin: const EdgeInsets.only(left: 42, right: 4, top: 0),
child: Material(
color: Theme.of(context).colorScheme.onInverseSurface,
color: theme.colorScheme.onInverseSurface,
borderRadius: BorderRadius.circular(6),
clipBehavior: Clip.hardEdge,
animationDuration: Duration.zero,
@@ -471,14 +468,9 @@ class ReplyItemGrpc extends StatelessWidget {
excludeSemantics: true,
child: Text.rich(
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.bodyMedium!
.fontSize,
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.85),
fontSize: theme.textTheme.bodyMedium!.fontSize,
color:
theme.colorScheme.onSurface.withOpacity(0.85),
height: 1.6),
overflow: TextOverflow.ellipsis,
maxLines: 2,
@@ -487,7 +479,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: replyItem.replies[i].member.name,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
@@ -521,8 +513,8 @@ class ReplyItemGrpc extends StatelessWidget {
),
buildContent(
context,
theme,
replyItem.replies[i],
replyReply,
replyItem,
null,
null,
@@ -544,24 +536,21 @@ class ReplyItemGrpc extends StatelessWidget {
child: Text.rich(
TextSpan(
style: TextStyle(
fontSize:
Theme.of(context).textTheme.labelMedium!.fontSize,
fontSize: theme.textTheme.labelMedium!.fontSize,
),
children: [
if (replyItem.replyControl.upReply)
TextSpan(
text: 'UP主等人 ',
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.85),
color:
theme.colorScheme.onSurface.withOpacity(0.85),
),
),
TextSpan(
text: replyItem.replyControl.subReplyEntryText,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
)
],
@@ -577,11 +566,11 @@ class ReplyItemGrpc extends StatelessWidget {
InlineSpan buildContent(
BuildContext context,
replyItem,
replyReply,
fReplyItem,
textPainter,
didExceedMaxLines,
ThemeData theme,
ReplyInfo replyItem,
ReplyInfo? fReplyItem,
TextPainter? textPainter,
bool? didExceedMaxLines,
) {
final String routePath = Get.currentRoute;
bool isVideoPage = routePath.startsWith('/video');
@@ -594,7 +583,7 @@ class ReplyItemGrpc extends StatelessWidget {
final List<InlineSpan> spanChildren = <InlineSpan>[];
if (didExceedMaxLines == true) {
final textSize = textPainter.size;
final textSize = textPainter!.size;
final double maxHeight = textPainter.preferredLineHeight * 6;
var position = textPainter.getPositionForOffset(
Offset(textSize.width, maxHeight),
@@ -609,7 +598,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: '投票: ${content.vote.title}',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
@@ -689,7 +678,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: matchStr,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
@@ -724,7 +713,7 @@ class ReplyItemGrpc extends StatelessWidget {
text: isValid ? ' $matchStr ' : matchStr,
style: isValid && isVideoPage
? TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
)
: null,
recognizer: isValid
@@ -765,7 +754,7 @@ class ReplyItemGrpc extends StatelessWidget {
imageUrl: Utils.thumbnailImgUrl(
content.url[matchStr]!.prefixIcon),
height: 19,
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
placeholder: (context, url) {
return const SizedBox.shrink();
},
@@ -775,7 +764,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: content.url[matchStr]!.title,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () async {
@@ -827,7 +816,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: matchStr,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
@@ -845,7 +834,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: matchStr,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
@@ -885,7 +874,7 @@ class ReplyItemGrpc extends StatelessWidget {
imageUrl: Utils.thumbnailImgUrl(
content.url[patternStr]!.prefixIcon),
height: 19,
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
placeholder: (context, url) {
return const SizedBox.shrink();
},
@@ -895,7 +884,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: content.url[patternStr]!.title,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
@@ -927,7 +916,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: '\n查看更多',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
),
);
@@ -965,7 +954,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: ' 笔记',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap =
@@ -1040,6 +1029,7 @@ class ReplyItemGrpc extends StatelessWidget {
bool? isDelete = await showDialog<bool>(
context: context,
builder: (context) {
final theme = Theme.of(context);
return AlertDialog(
title: const Text('删除评论'),
content: Text.rich(
@@ -1050,7 +1040,7 @@ class ReplyItemGrpc extends StatelessWidget {
TextSpan(
text: '@${item.member.name}',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
),
TextSpan(text: ':\n'),
@@ -1067,7 +1057,7 @@ class ReplyItemGrpc extends StatelessWidget {
child: Text(
'取消',
style: TextStyle(
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
),
@@ -1114,7 +1104,9 @@ class ReplyItemGrpc extends StatelessWidget {
}
}
Color errorColor = Theme.of(context).colorScheme.error;
final theme = Theme.of(context);
Color errorColor = theme.colorScheme.error;
final style = theme.textTheme.titleSmall;
return Padding(
padding:
@@ -1136,7 +1128,7 @@ class ReplyItemGrpc extends StatelessWidget {
width: 32,
height: 3,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
borderRadius: const BorderRadius.all(Radius.circular(3))),
),
),
@@ -1147,48 +1139,42 @@ class ReplyItemGrpc extends StatelessWidget {
onTap: () => menuActionHandler('delete'),
minLeadingWidth: 0,
leading: Icon(Icons.delete_outlined, color: errorColor, size: 19),
title: Text('删除',
style: Theme.of(context)
.textTheme
.titleSmall!
.copyWith(color: errorColor)),
title: Text('删除', style: style!.copyWith(color: errorColor)),
),
if (ownerMid != 0)
ListTile(
onTap: () => menuActionHandler('report'),
minLeadingWidth: 0,
leading: Icon(Icons.error_outline, color: errorColor, size: 19),
title: Text('举报',
style: Theme.of(context)
.textTheme
.titleSmall!
.copyWith(color: errorColor)),
title: Text('举报', style: style!.copyWith(color: errorColor)),
),
if (replyLevel == '1' && isSubReply.not && ownerMid == upMid.toInt())
ListTile(
onTap: () => menuActionHandler('top'),
minLeadingWidth: 0,
leading: Icon(Icons.vertical_align_top, size: 19),
title: Text('${replyItem.replyControl.isUpTop ? '取消' : ''}置顶',
style: Theme.of(context).textTheme.titleSmall!),
title: Text(
'${replyItem.replyControl.isUpTop ? '取消' : ''}置顶',
style: style,
),
),
ListTile(
onTap: () => menuActionHandler('copyAll'),
minLeadingWidth: 0,
leading: const Icon(Icons.copy_all_outlined, size: 19),
title: Text('复制全部', style: Theme.of(context).textTheme.titleSmall),
title: Text('复制全部', style: style),
),
ListTile(
onTap: () => menuActionHandler('copyFreedom'),
minLeadingWidth: 0,
leading: const Icon(Icons.copy_outlined, size: 19),
title: Text('自由复制', style: Theme.of(context).textTheme.titleSmall),
title: Text('自由复制', style: style),
),
ListTile(
onTap: () => menuActionHandler('saveReply'),
minLeadingWidth: 0,
leading: const Icon(Icons.save_alt, size: 19),
title: Text('保存评论', style: Theme.of(context).textTheme.titleSmall),
title: Text('保存评论', style: style),
),
if (item.mid.toInt() == ownerMid)
ListTile(
@@ -1201,8 +1187,7 @@ class ReplyItemGrpc extends StatelessWidget {
const Icon(Icons.reply, size: 12),
],
),
title:
Text('检查评论', style: Theme.of(context).textTheme.titleSmall),
title: Text('检查评论', style: style),
),
],
),

View File

@@ -102,9 +102,9 @@ class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
@override
Widget build(BuildContext context) {
final ThemeData t = Theme.of(context);
final Color color = t.colorScheme.outline;
final Color primary = t.colorScheme.primary;
final ThemeData theme = Theme.of(context);
final Color color = theme.colorScheme.outline;
final Color primary = theme.colorScheme.primary;
return Row(
mainAxisSize: MainAxisSize.min,
children: [
@@ -160,7 +160,7 @@ class _ZanButtonGrpcState extends State<ZanButtonGrpc> {
color: widget.replyItem.replyControl.action.toInt() == 1
? primary
: color,
fontSize: t.textTheme.labelSmall!.fontSize,
fontSize: theme.textTheme.labelSmall!.fontSize,
),
),
),

View File

@@ -16,6 +16,7 @@ class ToolbarIconButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return SizedBox(
width: 36,
height: 36,
@@ -23,16 +24,14 @@ class ToolbarIconButton extends StatelessWidget {
tooltip: tooltip,
onPressed: onPressed,
icon: icon,
highlightColor: Theme.of(context).colorScheme.secondaryContainer,
highlightColor: theme.colorScheme.secondaryContainer,
color: selected
? Theme.of(context).colorScheme.onSecondaryContainer
: Theme.of(context).colorScheme.outline,
? theme.colorScheme.onSecondaryContainer
: theme.colorScheme.outline,
style: ButtonStyle(
padding: WidgetStateProperty.all(EdgeInsets.zero),
backgroundColor: WidgetStateProperty.resolveWith((states) {
return selected
? Theme.of(context).colorScheme.secondaryContainer
: null;
return selected ? theme.colorScheme.secondaryContainer : null;
}),
),
),

View File

@@ -93,8 +93,8 @@ class _VideoReplyReplyPanelState
super.dispose();
}
Widget get _header => firstFloor == null
? _sortWidget
Widget _header(ThemeData theme) => firstFloor == null
? _sortWidget(theme)
: ValueListenableBuilder<Iterable<ItemPosition>>(
valueListenable: itemPositionsListener.itemPositions,
builder: (context, positions, child) {
@@ -109,139 +109,144 @@ class _VideoReplyReplyPanelState
: min)
.index;
}
return min >= 2 ? _sortWidget : const SizedBox.shrink();
return min >= 2 ? _sortWidget(theme) : const SizedBox.shrink();
},
);
@override
Widget get buildPage => Scaffold(
key: _key,
resizeToAvoidBottomInset: false,
body: Column(
children: [
widget.source == 'videoDetail'
? Container(
height: 45,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color:
Theme.of(context).dividerColor.withOpacity(0.1),
),
Widget buildPage(ThemeData theme) {
return Scaffold(
key: _key,
resizeToAvoidBottomInset: false,
body: Column(
children: [
widget.source == 'videoDetail'
? Container(
height: 45,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: theme.dividerColor.withOpacity(0.1),
),
),
padding: const EdgeInsets.only(left: 12, right: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(widget.isDialogue ? '对话列表' : '评论详情'),
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close, size: 20),
onPressed: Get.back,
),
],
),
)
: Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
Expanded(
child: enableSlide ? slideList() : buildList,
),
],
),
);
padding: const EdgeInsets.only(left: 12, right: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(widget.isDialogue ? '对话列表' : '评论详情'),
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close, size: 20),
onPressed: Get.back,
),
],
),
)
: Divider(
height: 1,
color: theme.dividerColor.withOpacity(0.1),
),
Expanded(
child: enableSlide ? slideList(theme) : buildList(theme),
),
],
),
);
}
@override
Widget get buildList => ClipRect(
child: refreshIndicator(
onRefresh: () async {
await _videoReplyReplyController.onRefresh();
},
child: Obx(
() => Stack(
children: [
ScrollablePositionedList.builder(
key: _listKey,
itemPositionsListener: itemPositionsListener,
itemCount:
_itemCount(_videoReplyReplyController.loadingState.value),
itemScrollController:
_videoReplyReplyController.itemScrollCtr,
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) {
if (widget.isDialogue) {
return _buildBody(
_videoReplyReplyController.loadingState.value, index);
} else if (firstFloor != null) {
if (index == 0) {
return ReplyItemGrpc(
replyItem: firstFloor,
replyLevel: '2',
needDivider: false,
onReply: () {
_onReply(firstFloor, -1);
},
upMid: _videoReplyReplyController.upMid,
onViewImage: widget.onViewImage,
onDismissed: widget.onDismissed,
callback: _getImageCallback,
onCheckReply: (item) => _videoReplyReplyController
.onCheckReply(context, item),
onToggleTop: (isUpTop, rpid) =>
_videoReplyReplyController.onToggleTop(
index,
_videoReplyReplyController.oid,
_videoReplyReplyController.replyType.index,
isUpTop,
rpid,
),
);
} else if (index == 1) {
return Divider(
height: 20,
color:
Theme.of(context).dividerColor.withOpacity(0.1),
thickness: 6,
);
} else if (index == 2) {
return _sortWidget;
} else {
return _buildBody(
_videoReplyReplyController.loadingState.value,
index - 3);
}
Widget buildList(ThemeData theme) {
return ClipRect(
child: refreshIndicator(
onRefresh: () async {
await _videoReplyReplyController.onRefresh();
},
child: Obx(
() => Stack(
children: [
ScrollablePositionedList.builder(
key: _listKey,
itemPositionsListener: itemPositionsListener,
itemCount:
_itemCount(_videoReplyReplyController.loadingState.value),
itemScrollController: _videoReplyReplyController.itemScrollCtr,
physics: const AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) {
if (widget.isDialogue) {
return _buildBody(theme,
_videoReplyReplyController.loadingState.value, index);
} else if (firstFloor != null) {
if (index == 0) {
return ReplyItemGrpc(
replyItem: firstFloor,
replyLevel: '2',
needDivider: false,
onReply: () {
_onReply(firstFloor, -1);
},
upMid: _videoReplyReplyController.upMid,
onViewImage: widget.onViewImage,
onDismissed: widget.onDismissed,
callback: _getImageCallback,
onCheckReply: (item) => _videoReplyReplyController
.onCheckReply(context, item),
onToggleTop: (isUpTop, rpid) =>
_videoReplyReplyController.onToggleTop(
index,
_videoReplyReplyController.oid,
_videoReplyReplyController.replyType.index,
isUpTop,
rpid,
),
);
} else if (index == 1) {
return Divider(
height: 20,
color: theme.dividerColor.withOpacity(0.1),
thickness: 6,
);
} else if (index == 2) {
return _sortWidget(theme);
} else {
if (index == 0) {
return _sortWidget;
} else {
return _buildBody(
_videoReplyReplyController.loadingState.value,
index - 1);
}
return _buildBody(
theme,
_videoReplyReplyController.loadingState.value,
index - 3,
);
}
},
),
if (!widget.isDialogue &&
_videoReplyReplyController.loadingState.value is Success)
_header,
],
),
} else {
if (index == 0) {
return _sortWidget(theme);
} else {
return _buildBody(
theme,
_videoReplyReplyController.loadingState.value,
index - 1,
);
}
}
},
),
if (!widget.isDialogue &&
_videoReplyReplyController.loadingState.value is Success)
_header(theme),
],
),
),
);
),
);
}
Widget get _sortWidget => Container(
Widget _sortWidget(ThemeData theme) => Container(
height: 40,
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
color: theme.colorScheme.surface,
boxShadow: [
BoxShadow(
color: Theme.of(context).colorScheme.surface,
color: theme.colorScheme.surface,
offset: const Offset(0, -2),
),
],
@@ -264,7 +269,7 @@ class _VideoReplyReplyPanelState
icon: Icon(
Icons.sort,
size: 16,
color: Theme.of(context).colorScheme.secondary,
color: theme.colorScheme.secondary,
),
label: Obx(
() => Text(
@@ -273,7 +278,7 @@ class _VideoReplyReplyPanelState
: '按时间',
style: TextStyle(
fontSize: 13,
color: Theme.of(context).colorScheme.secondary,
color: theme.colorScheme.secondary,
),
),
),
@@ -384,7 +389,7 @@ class _VideoReplyReplyPanelState
});
}
Widget _buildBody(LoadingState loadingState, int index) {
Widget _buildBody(ThemeData theme, LoadingState loadingState, int index) {
return switch (loadingState) {
Loading() => IgnorePointer(
child: CustomScrollView(
@@ -416,7 +421,7 @@ class _VideoReplyReplyPanelState
: '没有更多了',
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
);
@@ -424,15 +429,15 @@ class _VideoReplyReplyPanelState
if (_videoReplyReplyController.index != null &&
_videoReplyReplyController.index == index) {
colorAnimation ??= ColorTween(
begin: Theme.of(context).colorScheme.onInverseSurface,
end: Theme.of(context).colorScheme.surface,
begin: theme.colorScheme.onInverseSurface,
end: theme.colorScheme.surface,
).animate(_videoReplyReplyController.controller!);
return AnimatedBuilder(
animation: colorAnimation!,
builder: (context, child) {
return ColoredBox(
color: colorAnimation!.value ??
Theme.of(context).colorScheme.onInverseSurface,
theme.colorScheme.onInverseSurface,
child: _replyItem(loadingState.response[index], index),
);
},

View File

@@ -33,136 +33,134 @@ class _ViewPointsPageState
int currentIndex = -1;
@override
Widget get buildPage => Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
automaticallyImplyLeading: false,
titleSpacing: 16,
title: const Text('分段信息'),
toolbarHeight: 45,
actions: [
Text(
'分段进度条',
style: TextStyle(fontSize: 16),
),
Obx(
() => Transform.scale(
alignment: Alignment.centerLeft,
scale: 0.8,
child: Switch(
thumbIcon: WidgetStateProperty.resolveWith<Icon?>((states) {
if (states.isNotEmpty &&
states.first == WidgetState.selected) {
return const Icon(Icons.done);
}
return null;
}),
value: videoDetailController.plPlayerController.showVP.value,
onChanged: (value) {
videoDetailController.plPlayerController.showVP.value =
value;
},
),
Widget buildPage(ThemeData theme) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
automaticallyImplyLeading: false,
titleSpacing: 16,
title: const Text('分段信息'),
toolbarHeight: 45,
actions: [
Text(
'分段进度条',
style: TextStyle(fontSize: 16),
),
Obx(
() => Transform.scale(
alignment: Alignment.centerLeft,
scale: 0.8,
child: Switch(
thumbIcon: WidgetStateProperty.resolveWith<Icon?>((states) {
if (states.isNotEmpty &&
states.first == WidgetState.selected) {
return const Icon(Icons.done);
}
return null;
}),
value: videoDetailController.plPlayerController.showVP.value,
onChanged: (value) {
videoDetailController.plPlayerController.showVP.value = value;
},
),
),
iconButton(
context: context,
size: 30,
icon: Icons.clear,
tooltip: '关闭',
onPressed: Get.back,
),
const SizedBox(width: 16),
],
bottom: PreferredSize(
preferredSize: Size.fromHeight(1),
child: Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
),
iconButton(
context: context,
size: 30,
icon: Icons.clear,
tooltip: '关闭',
onPressed: Get.back,
),
const SizedBox(width: 16),
],
bottom: PreferredSize(
preferredSize: Size.fromHeight(1),
child: Divider(
height: 1,
color: theme.dividerColor.withOpacity(0.1),
),
),
body: enableSlide ? slideList() : buildList,
);
),
body: enableSlide ? slideList(theme) : buildList(theme),
);
}
@override
Widget get buildList => ListView.separated(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
padding:
EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom + 80),
itemCount: videoDetailController.viewPointList.length,
itemBuilder: (context, index) {
Segment segment = videoDetailController.viewPointList[index];
if (currentIndex == -1 &&
segment.from != null &&
segment.to != null) {
if (videoDetailController
.plPlayerController.positionSeconds.value >=
segment.from! &&
videoDetailController.plPlayerController.positionSeconds.value <
segment.to!) {
currentIndex = index;
}
Widget buildList(ThemeData theme) {
return ListView.separated(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
padding:
EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom + 80),
itemCount: videoDetailController.viewPointList.length,
itemBuilder: (context, index) {
Segment segment = videoDetailController.viewPointList[index];
if (currentIndex == -1 && segment.from != null && segment.to != null) {
if (videoDetailController.plPlayerController.positionSeconds.value >=
segment.from! &&
videoDetailController.plPlayerController.positionSeconds.value <
segment.to!) {
currentIndex = index;
}
return ListTile(
dense: true,
onTap: segment.from != null
? () {
currentIndex = index;
plPlayerController?.danmakuController?.clear();
plPlayerController?.videoPlayerController
?.seek(Duration(seconds: segment.from!));
Get.back();
}
: null,
leading: segment.url?.isNotEmpty == true
? Container(
margin: const EdgeInsets.symmetric(vertical: 6),
decoration: currentIndex == index
? BoxDecoration(
borderRadius: BorderRadius.circular(6),
border: Border.all(
width: 1.8,
strokeAlign: BorderSide.strokeAlignOutside,
color: Theme.of(context).colorScheme.primary,
),
)
: null,
child: LayoutBuilder(
builder: (context, constraints) => NetworkImgLayer(
radius: 6,
src: segment.url,
width: constraints.maxHeight * StyleString.aspectRatio,
height: constraints.maxHeight,
),
}
return ListTile(
dense: true,
onTap: segment.from != null
? () {
currentIndex = index;
plPlayerController?.danmakuController?.clear();
plPlayerController?.videoPlayerController
?.seek(Duration(seconds: segment.from!));
Get.back();
}
: null,
leading: segment.url?.isNotEmpty == true
? Container(
margin: const EdgeInsets.symmetric(vertical: 6),
decoration: currentIndex == index
? BoxDecoration(
borderRadius: BorderRadius.circular(6),
border: Border.all(
width: 1.8,
strokeAlign: BorderSide.strokeAlignOutside,
color: theme.colorScheme.primary,
),
)
: null,
child: LayoutBuilder(
builder: (context, constraints) => NetworkImgLayer(
radius: 6,
src: segment.url,
width: constraints.maxHeight * StyleString.aspectRatio,
height: constraints.maxHeight,
),
)
: null,
title: Text(
segment.title ?? '',
style: TextStyle(
fontSize: 14,
fontWeight: currentIndex == index ? FontWeight.bold : null,
color: currentIndex == index
? Theme.of(context).colorScheme.primary
: null,
),
),
)
: null,
title: Text(
segment.title ?? '',
style: TextStyle(
fontSize: 14,
fontWeight: currentIndex == index ? FontWeight.bold : null,
color: currentIndex == index ? theme.colorScheme.primary : null,
),
subtitle: Text(
'${segment.from != null ? Utils.timeFormat(segment.from) : ''} - ${segment.to != null ? Utils.timeFormat(segment.to) : ''}',
style: TextStyle(
fontSize: 13,
color: currentIndex == index
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.outline,
),
),
subtitle: Text(
'${segment.from != null ? Utils.timeFormat(segment.from) : ''} - ${segment.to != null ? Utils.timeFormat(segment.to) : ''}',
style: TextStyle(
fontSize: 13,
color: currentIndex == index
? theme.colorScheme.primary
: theme.colorScheme.outline,
),
);
},
separatorBuilder: (context, index) => Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
);
),
);
},
separatorBuilder: (context, index) => Divider(
height: 1,
color: theme.dividerColor.withOpacity(0.1),
),
);
}
}

View File

@@ -1,10 +1,7 @@
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/pages/common/common_collapse_slide_page.dart';
import 'package:PiliPlus/pages/video/detail/controller.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:PiliPlus/models/video/ai.dart';
import 'package:PiliPlus/utils/utils.dart';
@@ -22,199 +19,133 @@ class AiDetail extends CommonCollapseSlidePage {
}
class _AiDetailState extends CommonCollapseSlidePageState<AiDetail> {
InlineSpan buildContent(BuildContext context, content) {
List descV2 = content.descV2;
// type
// 1 普通文本
// 2 @用户
List<TextSpan> spanChildren = List.generate(descV2.length, (index) {
final currentDesc = descV2[index];
switch (currentDesc.type) {
case 1:
List<InlineSpan> spanChildren = [];
RegExp urlRegExp = RegExp(Constants.urlPattern);
Iterable<Match> matches = urlRegExp.allMatches(currentDesc.rawText);
int previousEndIndex = 0;
for (Match match in matches) {
if (match.start > previousEndIndex) {
spanChildren.add(TextSpan(
text: currentDesc.rawText
.substring(previousEndIndex, match.start)));
}
spanChildren.add(
TextSpan(
text: match.group(0),
style: TextStyle(color: Theme.of(context).colorScheme.primary),
recognizer: TapGestureRecognizer()
..onTap = () {
try {
PageUtils.handleWebview(match.group(0)!);
} catch (err) {
SmartDialog.showToast(err.toString());
}
},
@override
Widget buildPage(ThemeData theme) {
return Material(
color: theme.colorScheme.surface,
child: Column(
children: [
GestureDetector(
onTap: Get.back,
child: Container(
height: 35,
padding: const EdgeInsets.only(bottom: 2),
child: Center(
child: Container(
width: 32,
height: 3,
decoration: BoxDecoration(
color: theme.colorScheme.primary,
borderRadius: const BorderRadius.all(Radius.circular(3)),
),
),
),
);
previousEndIndex = match.end;
}
if (previousEndIndex < currentDesc.rawText.length) {
spanChildren.add(TextSpan(
text: currentDesc.rawText.substring(previousEndIndex)));
}
TextSpan result = TextSpan(children: spanChildren);
return result;
case 2:
final colorSchemePrimary = Theme.of(context).colorScheme.primary;
final heroTag = Utils.makeHeroTag(currentDesc.bizId);
return TextSpan(
text: '@${currentDesc.rawText}',
style: TextStyle(color: colorSchemePrimary),
recognizer: TapGestureRecognizer()
..onTap = () {
Get.toNamed(
'/member?mid=${currentDesc.bizId}',
arguments: {'face': '', 'heroTag': heroTag},
);
},
);
default:
return const TextSpan();
}
});
return TextSpan(children: spanChildren);
),
),
Expanded(
child: enableSlide ? slideList(theme) : buildList(theme),
),
],
),
);
}
@override
Widget get buildPage => Material(
color: Theme.of(context).colorScheme.surface,
child: Column(
children: [
GestureDetector(
onTap: Get.back,
child: Container(
height: 35,
padding: const EdgeInsets.only(bottom: 2),
child: Center(
child: Container(
width: 32,
height: 3,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: const BorderRadius.all(Radius.circular(3)),
),
),
Widget buildList(ThemeData theme) {
return CustomScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
slivers: [
if (widget.modelResult.summary?.isNotEmpty == true) ...[
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 14),
child: SelectableText(
widget.modelResult.summary!,
style: const TextStyle(
fontSize: 15,
height: 1.5,
),
),
),
Expanded(
child: enableSlide ? slideList() : buildList,
),
],
),
);
@override
Widget get buildList => CustomScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
slivers: [
if (widget.modelResult.summary?.isNotEmpty == true) ...[
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 14),
child: SelectableText(
widget.modelResult.summary!,
style: const TextStyle(
fontSize: 15,
height: 1.5,
),
),
),
),
if (widget.modelResult.outline?.isNotEmpty == true)
SliverToBoxAdapter(
child: Divider(
height: 20,
color: Theme.of(context).dividerColor.withOpacity(0.1),
thickness: 6,
),
),
],
),
if (widget.modelResult.outline?.isNotEmpty == true)
SliverPadding(
padding: EdgeInsets.only(
left: 14,
right: 14,
bottom: MediaQuery.paddingOf(context).bottom + 80,
),
sliver: SliverList.builder(
itemCount: widget.modelResult.outline!.length,
itemBuilder: (context, index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (index != 0) const SizedBox(height: 10),
SelectableText(
widget.modelResult.outline![index].title!,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
height: 1.5,
),
),
const SizedBox(height: 6),
if (widget.modelResult.outline![index].partOutline
?.isNotEmpty ==
true)
...widget.modelResult.outline![index].partOutline!.map(
(item) => Wrap(
children: [
SelectableText.rich(
TextSpan(
style: TextStyle(
fontSize: 14,
color:
Theme.of(context).colorScheme.onSurface,
height: 1.5,
),
children: [
TextSpan(
text:
Utils.formatDuration(item.timestamp!),
style: TextStyle(
color: Theme.of(context)
.colorScheme
.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
// 跳转到指定位置
try {
Get.find<VideoDetailController>(
tag: Get
.arguments['heroTag'])
.plPlayerController
.seekTo(Duration(
seconds: item.timestamp!));
} catch (_) {}
},
),
const TextSpan(text: ' '),
TextSpan(text: item.content!),
],
),
),
],
),
),
],
);
},
SliverToBoxAdapter(
child: Divider(
height: 20,
color: theme.dividerColor.withOpacity(0.1),
thickness: 6,
),
),
],
);
if (widget.modelResult.outline?.isNotEmpty == true)
SliverPadding(
padding: EdgeInsets.only(
left: 14,
right: 14,
bottom: MediaQuery.paddingOf(context).bottom + 80,
),
sliver: SliverList.builder(
itemCount: widget.modelResult.outline!.length,
itemBuilder: (context, index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (index != 0) const SizedBox(height: 10),
SelectableText(
widget.modelResult.outline![index].title!,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
height: 1.5,
),
),
const SizedBox(height: 6),
if (widget.modelResult.outline![index].partOutline
?.isNotEmpty ==
true)
...widget.modelResult.outline![index].partOutline!.map(
(item) => Wrap(
children: [
SelectableText.rich(
TextSpan(
style: TextStyle(
fontSize: 14,
color: theme.colorScheme.onSurface,
height: 1.5,
),
children: [
TextSpan(
text: Utils.formatDuration(item.timestamp!),
style: TextStyle(
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
// 跳转到指定位置
try {
Get.find<VideoDetailController>(
tag: Get.arguments['heroTag'])
.plPlayerController
.seekTo(Duration(
seconds: item.timestamp!));
} catch (_) {}
},
),
const TextSpan(text: ' '),
TextSpan(text: item.content!),
],
),
),
],
),
),
],
);
},
),
),
],
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -78,9 +78,9 @@ class _MediaListPanelState
}
@override
Widget get buildPage {
Widget buildPage(ThemeData theme) {
return Material(
color: Theme.of(context).colorScheme.surface,
color: theme.colorScheme.surface,
child: Column(
children: [
AppBar(
@@ -111,10 +111,10 @@ class _MediaListPanelState
),
Divider(
height: 1,
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
color: theme.colorScheme.outline.withOpacity(0.1),
),
Expanded(
child: enableSlide ? slideList() : buildList,
child: enableSlide ? slideList(theme) : buildList(theme),
),
],
),
@@ -122,16 +122,18 @@ class _MediaListPanelState
}
@override
Widget get buildList => widget.loadPrevious != null
? refreshIndicator(
onRefresh: () async {
await widget.loadPrevious!();
},
child: _buildList,
)
: _buildList;
Widget buildList(ThemeData theme) {
return widget.loadPrevious != null
? refreshIndicator(
onRefresh: () async {
await widget.loadPrevious!();
},
child: _buildList(theme),
)
: _buildList(theme);
}
Widget get _buildList => Obx(
Widget _buildList(ThemeData theme) => Obx(
() {
final showDelBtn =
widget.onDelete != null && widget.mediaList.length > 1;
@@ -172,7 +174,6 @@ class _MediaListPanelState
},
onLongPress: () {
imageSaveDialog(
context: context,
title: item.title,
cover: item.cover,
);
@@ -225,9 +226,7 @@ class _MediaListPanelState
? FontWeight.bold
: null,
color: item.bvid == widget.getBvId()
? Theme.of(context)
.colorScheme
.primary
? theme.colorScheme.primary
: null,
),
),
@@ -236,8 +235,7 @@ class _MediaListPanelState
item.upper!.name!,
style: TextStyle(
fontSize: 12,
color:
Theme.of(context).colorScheme.outline,
color: theme.colorScheme.outline,
),
),
const SizedBox(height: 3),
@@ -283,9 +281,7 @@ class _MediaListPanelState
child: Icon(
Icons.clear,
size: 18,
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
color: theme.colorScheme.onSurfaceVariant,
),
),
),