mod: 视频详情页样式

This commit is contained in:
guozhigq
2023-07-22 22:30:50 +08:00
parent 057b00f538
commit 8076848df3
7 changed files with 552 additions and 278 deletions

View File

@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:pilipala/common/constants.dart';
class ActionItem extends StatelessWidget {
Icon? icon;
Icon? selectIcon;
Function? onTap;
bool? loadingStatus;
String? text;
bool selectStatus = false;
ActionItem({
Key? key,
this.icon,
this.selectIcon,
this.onTap,
this.loadingStatus,
this.text,
required this.selectStatus,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => onTap!(),
borderRadius: StyleString.mdRadius,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 4),
selectStatus
? Icon(selectIcon!.icon!,
size: 21, color: Theme.of(context).primaryColor)
: Icon(icon!.icon!,
size: 21, color: Theme.of(context).colorScheme.outline),
const SizedBox(height: 4),
AnimatedOpacity(
opacity: loadingStatus! ? 0 : 1,
duration: const Duration(milliseconds: 200),
child: Text(
text ?? '',
style: TextStyle(
color: selectStatus
? Theme.of(context).primaryColor
: Theme.of(context).colorScheme.outline,
fontSize: Theme.of(context).textTheme.labelSmall?.fontSize),
),
),
],
),
);
}
}

View File

@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:pilipala/common/constants.dart';
class ActionRowItem extends StatelessWidget {
Icon? icon;
Icon? selectIcon;
Function? onTap;
bool? loadingStatus;
String? text;
bool selectStatus = false;
ActionRowItem({
Key? key,
this.icon,
this.selectIcon,
this.onTap,
this.loadingStatus,
this.text,
required this.selectStatus,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Material(
color: selectStatus
? Theme.of(context).colorScheme.primaryContainer.withOpacity(0.6)
: Theme.of(context).highlightColor.withOpacity(0.2),
borderRadius: const BorderRadius.all(Radius.circular(30)),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => onTap!(),
child: Padding(
padding: const EdgeInsets.fromLTRB(13, 6.5, 15, 6.3),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null) ...[
Icon(icon!.icon!,
size: 13,
color: selectStatus
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.onSecondaryContainer),
const SizedBox(width: 6),
],
AnimatedOpacity(
opacity: loadingStatus! ? 0 : 1,
duration: const Duration(milliseconds: 200),
child: Text(
text ?? '',
style: TextStyle(
color: selectStatus
? Theme.of(context).colorScheme.primary
: null,
fontSize:
Theme.of(context).textTheme.labelMedium?.fontSize),
),
),
],
),
),
),
);
}
}

View File

@ -0,0 +1,140 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/common/widgets/stat/danmu.dart';
import 'package:pilipala/common/widgets/stat/view.dart';
import 'package:pilipala/utils/utils.dart';
class IntroDetail extends StatelessWidget {
var videoDetail;
IntroDetail({
Key? key,
this.videoDetail,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).colorScheme.background,
padding: const EdgeInsets.only(left: 14, right: 14),
height: 570,
child: Column(
children: [
Container(
height: 25,
padding: const EdgeInsets.only(bottom: 2),
child: Center(
child: Container(
width: 40,
height: 3,
decoration: BoxDecoration(
color: Theme.of(context)
.colorScheme
.onSecondaryContainer
.withOpacity(0.5),
borderRadius: const BorderRadius.all(Radius.circular(3))),
),
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
videoDetail!.title,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
letterSpacing: 0.5, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Row(
children: [
const SizedBox(width: 2),
StatView(
theme: 'black',
view: videoDetail!.stat!.view,
size: 'medium',
),
const SizedBox(width: 10),
StatDanMu(
theme: 'black',
danmu: videoDetail!.stat!.danmaku,
size: 'medium',
),
const SizedBox(width: 10),
Text(
Utils.dateFormat(videoDetail!.pubdate,
formatType: 'detail'),
style: const TextStyle(fontSize: 12),
),
],
),
const SizedBox(height: 20),
SizedBox(
width: double.infinity,
child: SelectableRegion(
magnifierConfiguration:
const TextMagnifierConfiguration(),
focusNode: FocusNode(),
selectionControls: MaterialTextSelectionControls(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(videoDetail!.bvid!),
const SizedBox(height: 4),
Text.rich(
TextSpan(
children: [
buildContent(context, videoDetail!),
],
),
),
],
),
),
),
],
),
),
)
],
));
}
InlineSpan buildContent(BuildContext context, content) {
String desc = content.desc;
List descV2 = content.descV2;
// type
// 1 普通文本
// 2 @用户
List<InlineSpan> spanChilds = [];
if (descV2.isNotEmpty) {
for (var i = 0; i < descV2.length; i++) {
if (descV2[i].type == 1) {
spanChilds.add(TextSpan(text: descV2[i].rawText));
} else if (descV2[i].type == 2) {
spanChilds.add(
TextSpan(
text: '@${descV2[i].rawText}',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () {
String heroTag = Utils.makeHeroTag(descV2[i].bizId);
Get.toNamed(
'/member?mid=${descV2[i].bizId}',
arguments: {'face': '', 'heroTag': heroTag},
);
},
),
);
}
}
} else {
spanChilds.add(TextSpan(text: desc));
}
return TextSpan(children: spanChilds);
}
}

View File

@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
class MenuRow extends StatelessWidget {
bool? loadingStatus;
MenuRow({
Key? key,
this.loadingStatus,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
color: Theme.of(context).colorScheme.background,
padding: const EdgeInsets.only(top: 9, bottom: 9, left: 12),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(children: [
actionRowLineItem(
context,
() => {},
loadingStatus,
'推荐',
selectStatus: true,
),
const SizedBox(width: 8),
actionRowLineItem(
context,
() => {},
loadingStatus,
'弹幕',
selectStatus: false,
),
const SizedBox(width: 8),
actionRowLineItem(
context,
() => {},
loadingStatus,
'评论列表',
selectStatus: false,
),
const SizedBox(width: 8),
actionRowLineItem(
context,
() => {},
loadingStatus,
'播放列表',
selectStatus: false,
),
]),
),
);
}
Widget actionRowLineItem(
context, Function? onTap, bool? loadingStatus, String? text,
{bool selectStatus = false}) {
return Material(
color: selectStatus
? Theme.of(context).highlightColor.withOpacity(0.2)
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(30)),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => onTap!(),
child: Container(
padding: const EdgeInsets.fromLTRB(13, 5.5, 13, 5.5),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(30)),
border: Border.all(
color: selectStatus
? Colors.transparent
: Theme.of(context).highlightColor.withOpacity(0.2),
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
AnimatedOpacity(
opacity: loadingStatus! ? 0 : 1,
duration: const Duration(milliseconds: 200),
child: Text(
text!,
style: TextStyle(
fontSize:
Theme.of(context).textTheme.labelMedium?.fontSize),
),
),
],
),
),
),
);
}
}