mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-28 13:20:16 +08:00
opt: get theme color
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -36,10 +36,11 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar,
|
||||
appBar: _buildAppBar(theme),
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -65,16 +66,16 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildReplyOptionWidget,
|
||||
_buildReplyOptionWidget(theme),
|
||||
const SizedBox(height: 5),
|
||||
_buildPrivateWidget,
|
||||
_buildPrivateWidget(theme),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_buildImageList,
|
||||
_buildImageList(theme),
|
||||
const SizedBox(height: 2),
|
||||
],
|
||||
),
|
||||
@@ -86,7 +87,7 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget get _buildImageList => Obx(
|
||||
Widget _buildImageList(ThemeData theme) => Obx(
|
||||
() => SizedBox(
|
||||
height: 100,
|
||||
child: ListView.separated(
|
||||
@@ -114,7 +115,7 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
height: 100,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Theme.of(context).colorScheme.secondaryContainer,
|
||||
color: theme.colorScheme.secondaryContainer,
|
||||
),
|
||||
child: Center(child: Icon(Icons.add, size: 35)),
|
||||
),
|
||||
@@ -129,7 +130,7 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
),
|
||||
);
|
||||
|
||||
PreferredSizeWidget get _buildAppBar => PreferredSize(
|
||||
PreferredSizeWidget _buildAppBar(ThemeData theme) => PreferredSize(
|
||||
preferredSize: Size.fromHeight(66),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -147,9 +148,7 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
backgroundColor: WidgetStateProperty.resolveWith(
|
||||
(states) {
|
||||
return Theme.of(context)
|
||||
.colorScheme
|
||||
.secondaryContainer;
|
||||
return theme.colorScheme.secondaryContainer;
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -157,7 +156,7 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
icon: Icon(
|
||||
Icons.arrow_back_outlined,
|
||||
size: 18,
|
||||
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
color: theme.colorScheme.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -193,127 +192,124 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
||||
),
|
||||
);
|
||||
|
||||
Widget get _buildPrivateWidget => PopupMenuButton(
|
||||
initialValue: _isPrivate,
|
||||
onOpened: controller.keepChatPanel,
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
_isPrivate = value;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context) => List.generate(
|
||||
2,
|
||||
(index) => PopupMenuItem<bool>(
|
||||
enabled: _publishTime != null && index == 1 ? false : true,
|
||||
value: index == 0 ? false : true,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
index == 0 ? Icons.visibility : Icons.visibility_off,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(index == 0 ? '所有人可见' : '仅自己可见'),
|
||||
],
|
||||
Widget _buildPrivateWidget(ThemeData theme) {
|
||||
final color =
|
||||
_isPrivate ? theme.colorScheme.error : theme.colorScheme.secondary;
|
||||
return PopupMenuButton(
|
||||
initialValue: _isPrivate,
|
||||
onOpened: controller.keepChatPanel,
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
_isPrivate = value;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context) => List.generate(
|
||||
2,
|
||||
(index) => PopupMenuItem<bool>(
|
||||
enabled: _publishTime != null && index == 1 ? false : true,
|
||||
value: index == 0 ? false : true,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
index == 0 ? Icons.visibility : Icons.visibility_off,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(index == 0 ? '所有人可见' : '仅自己可见'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
_isPrivate ? Icons.visibility_off : Icons.visibility,
|
||||
color: color,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
_isPrivate ? '仅自己可见' : '所有人可见',
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: color,
|
||||
),
|
||||
strutStyle: StrutStyle(leading: 0, height: 1),
|
||||
),
|
||||
Icon(
|
||||
size: 20,
|
||||
Icons.keyboard_arrow_right,
|
||||
color: color,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
_isPrivate ? Icons.visibility_off : Icons.visibility,
|
||||
color: _isPrivate
|
||||
? Theme.of(context).colorScheme.error
|
||||
: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
_isPrivate ? '仅自己可见' : '所有人可见',
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: _isPrivate
|
||||
? Theme.of(context).colorScheme.error
|
||||
: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
strutStyle: StrutStyle(leading: 0, height: 1),
|
||||
),
|
||||
Icon(
|
||||
size: 20,
|
||||
Icons.keyboard_arrow_right,
|
||||
color: _isPrivate
|
||||
? Theme.of(context).colorScheme.error
|
||||
: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget get _buildReplyOptionWidget => PopupMenuButton(
|
||||
initialValue: _replyOption,
|
||||
onOpened: controller.keepChatPanel,
|
||||
onSelected: (item) {
|
||||
setState(() {
|
||||
_replyOption = item;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context) => ReplyOption.values
|
||||
.map(
|
||||
(item) => PopupMenuItem<ReplyOption>(
|
||||
value: item,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
item.iconData,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(item.title),
|
||||
],
|
||||
),
|
||||
Widget _buildReplyOptionWidget(ThemeData theme) {
|
||||
final color = _replyOption == ReplyOption.close
|
||||
? theme.colorScheme.error
|
||||
: theme.colorScheme.secondary;
|
||||
return PopupMenuButton(
|
||||
initialValue: _replyOption,
|
||||
onOpened: controller.keepChatPanel,
|
||||
onSelected: (item) {
|
||||
setState(() {
|
||||
_replyOption = item;
|
||||
});
|
||||
},
|
||||
itemBuilder: (context) => ReplyOption.values
|
||||
.map(
|
||||
(item) => PopupMenuItem<ReplyOption>(
|
||||
value: item,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
item.iconData,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(item.title),
|
||||
],
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
_replyOption.iconData,
|
||||
color: _replyOption == ReplyOption.close
|
||||
? Theme.of(context).colorScheme.error
|
||||
: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
_replyOption.iconData,
|
||||
color: color,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
_replyOption.title,
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: color,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
_replyOption.title,
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
color: _replyOption == ReplyOption.close
|
||||
? Theme.of(context).colorScheme.error
|
||||
: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
strutStyle: StrutStyle(leading: 0, height: 1),
|
||||
),
|
||||
Icon(
|
||||
size: 20,
|
||||
Icons.keyboard_arrow_right,
|
||||
color: _replyOption == ReplyOption.close
|
||||
? Theme.of(context).colorScheme.error
|
||||
: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
strutStyle: StrutStyle(leading: 0, height: 1),
|
||||
),
|
||||
Icon(
|
||||
size: 20,
|
||||
Icons.keyboard_arrow_right,
|
||||
color: color,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget get _buildPubtimeWidget => _publishTime == null
|
||||
? FilledButton.tonal(
|
||||
|
||||
@@ -282,6 +282,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(
|
||||
@@ -353,14 +354,14 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
onRefresh: () async {
|
||||
await _dynamicDetailController.onRefresh();
|
||||
},
|
||||
child: _buildBody(context.orientation),
|
||||
child: _buildBody(context.orientation, theme),
|
||||
)
|
||||
: _buildBody(context.orientation),
|
||||
: _buildBody(context.orientation, theme),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody(Orientation orientation) => Stack(
|
||||
Widget _buildBody(Orientation orientation, ThemeData theme) => Stack(
|
||||
children: [
|
||||
Builder(
|
||||
builder: (context) {
|
||||
@@ -377,10 +378,10 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
callback: _getImageCallback,
|
||||
),
|
||||
),
|
||||
replyPersistentHeader(context),
|
||||
replyPersistentHeader(theme),
|
||||
Obx(
|
||||
() => replyList(
|
||||
_dynamicDetailController.loadingState.value),
|
||||
theme, _dynamicDetailController.loadingState.value),
|
||||
),
|
||||
]
|
||||
.map<Widget>((e) => SliverPadding(
|
||||
@@ -429,13 +430,15 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(right: padding / 4),
|
||||
sliver: replyPersistentHeader(context),
|
||||
sliver: replyPersistentHeader(theme),
|
||||
),
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(right: padding / 4),
|
||||
sliver: Obx(
|
||||
() => replyList(_dynamicDetailController
|
||||
.loadingState.value),
|
||||
() => replyList(
|
||||
theme,
|
||||
_dynamicDetailController
|
||||
.loadingState.value),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -499,12 +502,10 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
color: theme.colorScheme.surface,
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline
|
||||
color: theme.colorScheme.outline
|
||||
.withOpacity(0.08),
|
||||
),
|
||||
),
|
||||
@@ -565,17 +566,14 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
icon: Icon(
|
||||
FontAwesomeIcons.shareFromSquare,
|
||||
size: 16,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
semanticLabel: "转发",
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.fromLTRB(
|
||||
15, 0, 15, 0),
|
||||
foregroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
foregroundColor:
|
||||
theme.colorScheme.outline,
|
||||
),
|
||||
label: Text(
|
||||
_dynamicDetailController
|
||||
@@ -606,17 +604,14 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
icon: Icon(
|
||||
FontAwesomeIcons.shareNodes,
|
||||
size: 16,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
semanticLabel: "分享",
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.fromLTRB(
|
||||
15, 0, 15, 0),
|
||||
foregroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
foregroundColor:
|
||||
theme.colorScheme.outline,
|
||||
),
|
||||
label: const Text('分享'),
|
||||
),
|
||||
@@ -652,12 +647,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
?.like
|
||||
?.status ==
|
||||
true
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.outline,
|
||||
semanticLabel:
|
||||
_dynamicDetailController
|
||||
.item
|
||||
@@ -672,9 +663,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.fromLTRB(
|
||||
15, 0, 15, 0),
|
||||
foregroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
foregroundColor:
|
||||
theme.colorScheme.outline,
|
||||
),
|
||||
label: AnimatedSwitcher(
|
||||
duration: const Duration(
|
||||
@@ -709,12 +699,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
?.like
|
||||
?.status ==
|
||||
true
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -733,10 +719,10 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
],
|
||||
);
|
||||
|
||||
SliverPersistentHeader replyPersistentHeader(BuildContext context) {
|
||||
SliverPersistentHeader replyPersistentHeader(ThemeData theme) {
|
||||
return SliverPersistentHeader(
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
bgColor: Theme.of(context).colorScheme.surface,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 45,
|
||||
padding: const EdgeInsets.only(left: 12, right: 6),
|
||||
@@ -763,13 +749,13 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(() => Text(
|
||||
_dynamicDetailController.sortType.value.label,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
)),
|
||||
),
|
||||
@@ -782,7 +768,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
);
|
||||
}
|
||||
|
||||
Widget replyList(LoadingState<List<ReplyInfo>?> loadingState) {
|
||||
Widget replyList(
|
||||
ThemeData theme, LoadingState<List<ReplyInfo>?> loadingState) {
|
||||
return switch (loadingState) {
|
||||
Loading() => SliverList.builder(
|
||||
itemBuilder: (context, index) {
|
||||
@@ -808,7 +795,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
: '没有更多了',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -70,6 +70,7 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
return AnimatedSize(
|
||||
alignment: Alignment.topCenter,
|
||||
curve: Curves.ease,
|
||||
@@ -79,10 +80,13 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: _isMax ? 16 : 10),
|
||||
_buildAppBar,
|
||||
if (_isMax) Expanded(child: _buildEditPanel) else _buildEditPanel,
|
||||
_buildAppBar(theme),
|
||||
if (_isMax)
|
||||
Expanded(child: _buildEditPanel(theme))
|
||||
else
|
||||
_buildEditPanel(theme),
|
||||
if (_isMax.not)
|
||||
..._biuldDismiss
|
||||
..._biuldDismiss(theme)
|
||||
else ...[
|
||||
_buildToolbar,
|
||||
buildPanelContainer(Colors.transparent),
|
||||
@@ -92,7 +96,7 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget get _buildEditPanel => Column(
|
||||
Widget _buildEditPanel(ThemeData theme) => Column(
|
||||
mainAxisSize: _isMax ? MainAxisSize.max : MainAxisSize.min,
|
||||
children: [
|
||||
Flexible(
|
||||
@@ -105,28 +109,30 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
width: 2,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
child: _isMax.not ? _buildEditPlaceHolder : _buildEditWidget,
|
||||
child: _isMax.not
|
||||
? _buildEditPlaceHolder(theme)
|
||||
: _buildEditWidget,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_buildRefWidget,
|
||||
_buildRefWidget(theme),
|
||||
],
|
||||
);
|
||||
|
||||
Widget get _buildRefWidget => Container(
|
||||
Widget _buildRefWidget(ThemeData theme) => Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHigh ==
|
||||
Theme.of(context).colorScheme.surface
|
||||
? Theme.of(context).colorScheme.onInverseSurface
|
||||
: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
color: theme.colorScheme.surfaceContainerHigh ==
|
||||
theme.colorScheme.surface
|
||||
? theme.colorScheme.onInverseSurface
|
||||
: theme.colorScheme.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Row(
|
||||
@@ -149,7 +155,7 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
Text(
|
||||
'@$_uname',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
@@ -165,7 +171,7 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
),
|
||||
);
|
||||
|
||||
Widget get _buildEditPlaceHolder => GestureDetector(
|
||||
Widget _buildEditPlaceHolder(ThemeData theme) => GestureDetector(
|
||||
onTap: () async {
|
||||
setState(() => _isMax = true);
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
@@ -178,7 +184,7 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
style: TextStyle(
|
||||
height: 1.75,
|
||||
fontSize: 15,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -212,7 +218,7 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
),
|
||||
);
|
||||
|
||||
Widget get _buildAppBar => _isMax.not
|
||||
Widget _buildAppBar(ThemeData theme) => _isMax.not
|
||||
? Row(
|
||||
children: [
|
||||
const SizedBox(width: 16),
|
||||
@@ -253,14 +259,14 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
backgroundColor:
|
||||
WidgetStateProperty.resolveWith((states) {
|
||||
return Theme.of(context).colorScheme.secondaryContainer;
|
||||
return theme.colorScheme.secondaryContainer;
|
||||
}),
|
||||
),
|
||||
onPressed: Get.back,
|
||||
icon: Icon(
|
||||
Icons.arrow_back_outlined,
|
||||
size: 18,
|
||||
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
color: theme.colorScheme.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -316,11 +322,11 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
),
|
||||
);
|
||||
|
||||
List<Widget> get _biuldDismiss => [
|
||||
List<Widget> _biuldDismiss(ThemeData theme) => [
|
||||
const SizedBox(height: 10),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: Theme.of(context).colorScheme.outline.withOpacity(0.1),
|
||||
color: theme.colorScheme.outline.withOpacity(0.1),
|
||||
),
|
||||
ListTile(
|
||||
dense: true,
|
||||
@@ -328,7 +334,7 @@ class _RepostPanelState extends CommonPublishPageState<RepostPanel> {
|
||||
title: Center(
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -35,6 +35,14 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
final DynamicsController _dynamicsController = Get.put(DynamicsController());
|
||||
late UpPanelPosition upPanelPosition;
|
||||
|
||||
late ThemeData theme;
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
theme = Theme.of(context);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
@@ -49,7 +57,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
backgroundColor: WidgetStateProperty.resolveWith((states) {
|
||||
return Theme.of(context).colorScheme.secondaryContainer;
|
||||
return theme.colorScheme.secondaryContainer;
|
||||
}),
|
||||
),
|
||||
onPressed: () {
|
||||
@@ -65,7 +73,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
icon: Icon(
|
||||
Icons.add,
|
||||
size: 18,
|
||||
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
color: theme.colorScheme.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -103,7 +111,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
return Container(
|
||||
//抽屉模式增加底色
|
||||
color: upPanelPosition.index > 1
|
||||
? Theme.of(context).colorScheme.surface
|
||||
? theme.colorScheme.surface
|
||||
: Colors.transparent,
|
||||
width: 64,
|
||||
child: Obx(
|
||||
@@ -149,9 +157,9 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
dividerColor: Colors.transparent,
|
||||
dividerHeight: 0,
|
||||
tabAlignment: TabAlignment.center,
|
||||
indicatorColor: Theme.of(context).colorScheme.primary,
|
||||
labelColor: Theme.of(context).colorScheme.primary,
|
||||
unselectedLabelColor: Theme.of(context).colorScheme.onSurface,
|
||||
indicatorColor: theme.colorScheme.primary,
|
||||
labelColor: theme.colorScheme.primary,
|
||||
unselectedLabelColor: theme.colorScheme.onSurface,
|
||||
labelStyle:
|
||||
TabBarTheme.of(context).labelStyle?.copyWith(fontSize: 13) ??
|
||||
const TextStyle(fontSize: 13),
|
||||
|
||||
@@ -58,8 +58,10 @@ class _ActionPanelState extends State<ActionPanel> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var color = Theme.of(context).colorScheme.outline;
|
||||
var primary = Theme.of(context).colorScheme.primary;
|
||||
final theme = Theme.of(context);
|
||||
final color = theme.colorScheme.outline;
|
||||
final primary = theme.colorScheme.primary;
|
||||
final outline = theme.colorScheme.outline;
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
@@ -90,7 +92,7 @@ class _ActionPanelState extends State<ActionPanel> {
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
|
||||
foregroundColor: Theme.of(context).colorScheme.outline,
|
||||
foregroundColor: outline,
|
||||
),
|
||||
label: Text(
|
||||
widget.item.modules.moduleStat!.forward!.count != null
|
||||
@@ -113,7 +115,7 @@ class _ActionPanelState extends State<ActionPanel> {
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
|
||||
foregroundColor: Theme.of(context).colorScheme.outline,
|
||||
foregroundColor: outline,
|
||||
),
|
||||
label: Text(
|
||||
widget.item.modules.moduleStat!.comment!.count != null
|
||||
@@ -140,7 +142,7 @@ class _ActionPanelState extends State<ActionPanel> {
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.fromLTRB(15, 0, 15, 0),
|
||||
foregroundColor: Theme.of(context).colorScheme.outline,
|
||||
foregroundColor: outline,
|
||||
),
|
||||
label: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -6,33 +7,36 @@ import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
|
||||
/// TODO 点击跳转
|
||||
Widget addWidget(item, context, type, {floor = 1}) {
|
||||
Widget addWidget(
|
||||
ThemeData theme, DynamicItemModel item, BuildContext context, type,
|
||||
{floor = 1}) {
|
||||
Map<dynamic, dynamic> dynamicProperty = {
|
||||
'ADDITIONAL_TYPE_UGC': item.modules.moduleDynamic.additional.ugc,
|
||||
'ADDITIONAL_TYPE_UGC': item.modules.moduleDynamic!.additional!.ugc,
|
||||
// 直播预约
|
||||
'ADDITIONAL_TYPE_RESERVE': item.modules.moduleDynamic.additional.reserve,
|
||||
'ADDITIONAL_TYPE_RESERVE': item.modules.moduleDynamic!.additional!.reserve,
|
||||
// 商品
|
||||
'ADDITIONAL_TYPE_GOODS': item.modules.moduleDynamic.additional.goods,
|
||||
'ADDITIONAL_TYPE_GOODS': item.modules.moduleDynamic!.additional!.goods,
|
||||
// 比赛信息
|
||||
'ADDITIONAL_TYPE_MATCH': item.modules.moduleDynamic.additional.match,
|
||||
'ADDITIONAL_TYPE_MATCH': item.modules.moduleDynamic!.additional!.match,
|
||||
// 游戏信息
|
||||
'ADDITIONAL_TYPE_COMMON': item.modules.moduleDynamic.additional.common,
|
||||
'ADDITIONAL_TYPE_COMMON': item.modules.moduleDynamic!.additional!.common,
|
||||
};
|
||||
dynamic content = dynamicProperty[type];
|
||||
Color bgColor = floor == 1
|
||||
? Theme.of(context).dividerColor.withOpacity(0.08)
|
||||
: Theme.of(context).colorScheme.surface;
|
||||
? theme.dividerColor.withOpacity(0.08)
|
||||
: theme.colorScheme.surface;
|
||||
switch (type) {
|
||||
case 'ADDITIONAL_TYPE_UGC':
|
||||
// 转发的投稿
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
String text = dynamicProperty[type].jumpUrl;
|
||||
String text = content.jumpUrl;
|
||||
RegExp bvRegex = RegExp(r'BV[0-9A-Za-z]{10}', caseSensitive: false);
|
||||
Iterable<Match> matches = bvRegex.allMatches(text);
|
||||
if (matches.isNotEmpty) {
|
||||
Match match = matches.first;
|
||||
String bvid = match.group(0)!;
|
||||
String cover = dynamicProperty[type].cover;
|
||||
String cover = content.cover;
|
||||
try {
|
||||
int cid = await SearchHttp.ab2c(bvid: bvid);
|
||||
PageUtils.toVideoPage(
|
||||
@@ -58,7 +62,7 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
NetworkImgLayer(
|
||||
width: 120,
|
||||
height: 75,
|
||||
src: dynamicProperty[type].cover,
|
||||
src: content.cover,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
@@ -67,17 +71,16 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
dynamicProperty[type].title,
|
||||
content.title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
dynamicProperty[type].descSecond,
|
||||
content.descSecond,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
)
|
||||
],
|
||||
@@ -88,22 +91,22 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
),
|
||||
);
|
||||
case 'ADDITIONAL_TYPE_RESERVE':
|
||||
return dynamicProperty[type].state != -1
|
||||
? dynamicProperty[type].title != null
|
||||
return content.state != -1
|
||||
? content.title != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12, top: 10, right: 12, bottom: 10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 10),
|
||||
color: bgColor,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
dynamicProperty[type].title,
|
||||
content.title,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -111,21 +114,15 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelMedium!
|
||||
.fontSize),
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
children: [
|
||||
if (dynamicProperty[type].desc1 != null)
|
||||
TextSpan(
|
||||
text:
|
||||
dynamicProperty[type].desc1['text']),
|
||||
if (content.desc1 != null)
|
||||
TextSpan(text: content.desc1['text']),
|
||||
const TextSpan(text: ' '),
|
||||
if (dynamicProperty[type].desc2 != null)
|
||||
TextSpan(
|
||||
text:
|
||||
dynamicProperty[type].desc2['text']),
|
||||
if (content.desc2 != null)
|
||||
TextSpan(text: content.desc2['text']),
|
||||
],
|
||||
),
|
||||
)
|
||||
@@ -146,6 +143,6 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
case 'ADDITIONAL_TYPE_VOTE':
|
||||
return const SizedBox.shrink();
|
||||
default:
|
||||
return const Text('11');
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
|
||||
import '../../../common/constants.dart';
|
||||
import 'pic_panel.dart';
|
||||
|
||||
Widget articlePanel(source, item, context, callback, {floor = 1}) {
|
||||
TextStyle authorStyle =
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary);
|
||||
Widget articlePanel(
|
||||
ThemeData theme,
|
||||
String? source,
|
||||
DynamicItemModel item,
|
||||
BuildContext context,
|
||||
callback, {
|
||||
floor = 1,
|
||||
}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: Column(
|
||||
@@ -15,37 +21,32 @@ Widget articlePanel(source, item, context, callback, {floor = 1}) {
|
||||
if (floor == 2) ...[
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Text(
|
||||
'@${item.modules.moduleAuthor.name}',
|
||||
style: authorStyle,
|
||||
),
|
||||
Text(
|
||||
'@${item.modules.moduleAuthor!.name}',
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
Utils.dateFormat(item.modules.moduleAuthor.pubTs),
|
||||
Utils.dateFormat(item.modules.moduleAuthor!.pubTs),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize: Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelSmall!.fontSize),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
Text(
|
||||
item.modules.moduleDynamic.major.opus.title,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
item.modules.moduleDynamic!.major!.opus!.title!,
|
||||
style: theme.textTheme.titleMedium!
|
||||
.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
if (item.modules.moduleDynamic.major.opus.summary.text !=
|
||||
if (item.modules.moduleDynamic?.major?.opus?.summary?.text !=
|
||||
'undefined') ...[
|
||||
Text(
|
||||
item.modules.moduleDynamic.major.opus.summary.richTextNodes.first
|
||||
.text,
|
||||
item.modules.moduleDynamic!.major!.opus!.summary!.richTextNodes!
|
||||
.first.text!,
|
||||
maxLines: source == 'detail' ? null : 4,
|
||||
style: const TextStyle(height: 1.55),
|
||||
overflow: source == 'detail' ? null : TextOverflow.ellipsis,
|
||||
|
||||
@@ -241,6 +241,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
maxWidth: min(640, min(Get.width, Get.height)),
|
||||
),
|
||||
builder: (context1) {
|
||||
final theme = Theme.of(context);
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.only(bottom: MediaQuery.of(context1).padding.bottom),
|
||||
@@ -261,7 +262,7 @@ class AuthorPanel 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))),
|
||||
),
|
||||
@@ -283,7 +284,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
leading: const Icon(Icons.watch_later_outlined, size: 19),
|
||||
title: Text(
|
||||
'稍后再看',
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
style: theme.textTheme.titleSmall,
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
@@ -293,13 +294,12 @@ class AuthorPanel extends StatelessWidget {
|
||||
},
|
||||
minLeadingWidth: 0,
|
||||
leading: const Icon(Icons.save_alt, size: 19),
|
||||
title: Text('保存动态',
|
||||
style: Theme.of(context).textTheme.titleSmall!),
|
||||
title: Text('保存动态', style: theme.textTheme.titleSmall!),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(
|
||||
'分享动态',
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
style: theme.textTheme.titleSmall,
|
||||
),
|
||||
leading: const Icon(Icons.share_outlined, size: 19),
|
||||
onTap: () {
|
||||
@@ -314,7 +314,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
ListTile(
|
||||
title: Text(
|
||||
'分享至消息',
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
style: theme.textTheme.titleSmall,
|
||||
),
|
||||
leading: const Icon(Icons.forward_to_inbox, size: 19),
|
||||
onTap: () {
|
||||
@@ -359,7 +359,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
ListTile(
|
||||
title: Text(
|
||||
'临时屏蔽:${item.modules.moduleAuthor?.name}',
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
style: theme.textTheme.titleSmall,
|
||||
),
|
||||
leading: const Icon(Icons.visibility_off_outlined, size: 19),
|
||||
onTap: () {
|
||||
@@ -387,8 +387,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
Icon(Icons.published_with_changes_sharp, size: 12),
|
||||
],
|
||||
),
|
||||
title: Text('检查动态',
|
||||
style: Theme.of(context).textTheme.titleSmall!),
|
||||
title: Text('检查动态', style: theme.textTheme.titleSmall!),
|
||||
),
|
||||
if (onSetTop != null)
|
||||
ListTile(
|
||||
@@ -401,7 +400,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
leading: const Icon(Icons.vertical_align_top, size: 19),
|
||||
title: Text(
|
||||
'${item.modules.moduleTag?.text != null ? '取消' : ''}置顶',
|
||||
style: Theme.of(context).textTheme.titleSmall!),
|
||||
style: theme.textTheme.titleSmall!),
|
||||
),
|
||||
if (onRemove != null)
|
||||
ListTile(
|
||||
@@ -417,7 +416,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -434,24 +433,24 @@ class AuthorPanel extends StatelessWidget {
|
||||
},
|
||||
minLeadingWidth: 0,
|
||||
leading: Icon(Icons.delete_outline,
|
||||
color: Theme.of(context).colorScheme.error, size: 19),
|
||||
color: theme.colorScheme.error, size: 19),
|
||||
title: Text('删除',
|
||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||
color: Theme.of(context).colorScheme.error)),
|
||||
style: theme.textTheme.titleSmall!
|
||||
.copyWith(color: theme.colorScheme.error)),
|
||||
),
|
||||
],
|
||||
if (Accounts.main.isLogin)
|
||||
ListTile(
|
||||
title: Text(
|
||||
'举报',
|
||||
style: Theme.of(context).textTheme.titleSmall!.copyWith(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
style: theme.textTheme.titleSmall!.copyWith(
|
||||
color: theme.colorScheme.error,
|
||||
),
|
||||
),
|
||||
leading: Icon(
|
||||
Icons.error_outline_outlined,
|
||||
size: 19,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
color: theme.colorScheme.error,
|
||||
),
|
||||
onTap: () {
|
||||
Get.back();
|
||||
@@ -483,8 +482,7 @@ class AuthorPanel extends StatelessWidget {
|
||||
dense: true,
|
||||
title: Text(
|
||||
'取消',
|
||||
style:
|
||||
TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
// 内容
|
||||
import 'package:PiliPlus/common/widgets/image_view.dart';
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'rich_node_panel.dart';
|
||||
|
||||
Widget content(bool isSave, BuildContext context, item, source, callback) {
|
||||
Widget content(
|
||||
ThemeData theme,
|
||||
bool isSave,
|
||||
BuildContext context,
|
||||
DynamicItemModel item,
|
||||
String? source,
|
||||
Function(List<String>, int)? callback,
|
||||
) {
|
||||
InlineSpan picsNodes() {
|
||||
return WidgetSpan(
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) => imageView(
|
||||
constraints.maxWidth,
|
||||
(item.modules.moduleDynamic.major.opus.pics as List)
|
||||
(item.modules.moduleDynamic!.major!.opus!.pics as List)
|
||||
.map(
|
||||
(item) => ImageModel(
|
||||
width: item.width,
|
||||
@@ -26,9 +34,7 @@ Widget content(bool isSave, BuildContext context, item, source, callback) {
|
||||
);
|
||||
}
|
||||
|
||||
TextStyle authorStyle =
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary);
|
||||
InlineSpan? richNodes = richNode(item, context);
|
||||
TextSpan? richNodes = richNode(theme, item, context);
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
@@ -36,24 +42,17 @@ Widget content(bool isSave, BuildContext context, item, source, callback) {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (item.modules.moduleDynamic.topic != null) ...[
|
||||
GestureDetector(
|
||||
child: Text(
|
||||
'#${item.modules.moduleDynamic.topic.name}',
|
||||
style: authorStyle,
|
||||
),
|
||||
if (item.modules.moduleDynamic?.topic != null) ...[
|
||||
Text(
|
||||
'#${item.modules.moduleDynamic!.topic!.name}',
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
),
|
||||
],
|
||||
if (richNodes != null)
|
||||
source == 'detail'
|
||||
? SelectableRegion(
|
||||
magnifierConfiguration: const TextMagnifierConfiguration(),
|
||||
focusNode: FocusNode(),
|
||||
selectionControls: MaterialTextSelectionControls(),
|
||||
child: Text.rich(
|
||||
style: TextStyle(fontSize: !isSave ? 16 : 15),
|
||||
richNodes,
|
||||
),
|
||||
? SelectableText.rich(
|
||||
richNodes,
|
||||
style: TextStyle(fontSize: !isSave ? 16 : 15),
|
||||
)
|
||||
: Text.rich(
|
||||
style: const TextStyle(fontSize: 15),
|
||||
@@ -61,12 +60,8 @@ Widget content(bool isSave, BuildContext context, item, source, callback) {
|
||||
maxLines: 6,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
if (item.modules.moduleDynamic.major != null &&
|
||||
item.modules.moduleDynamic.major.opus != null &&
|
||||
item.modules.moduleDynamic.major.opus.pics.isNotEmpty)
|
||||
Text.rich(
|
||||
picsNodes(),
|
||||
),
|
||||
if (item.modules.moduleDynamic?.major?.opus?.pics?.isNotEmpty == true)
|
||||
Text.rich(picsNodes()),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -29,6 +29,7 @@ class DynamicPanel extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final authorWidget = AuthorPanel(
|
||||
item: item,
|
||||
source: source,
|
||||
@@ -45,7 +46,7 @@ class DynamicPanel extends StatelessWidget {
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
width: 8,
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.05),
|
||||
color: theme.dividerColor.withOpacity(0.05),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -76,8 +77,8 @@ class DynamicPanel extends StatelessWidget {
|
||||
),
|
||||
if (item.modules.moduleDynamic!.desc != null ||
|
||||
item.modules.moduleDynamic!.major != null)
|
||||
content(isSave, context, item, source, callback),
|
||||
forWard(isSave, item, context, source, callback),
|
||||
content(theme, isSave, context, item, source, callback),
|
||||
forWard(theme, isSave, item, context, source, callback),
|
||||
const SizedBox(height: 2),
|
||||
if (source == null) ActionPanel(item: item),
|
||||
if (source == 'detail' && !isSave) const SizedBox(height: 12),
|
||||
@@ -121,7 +122,6 @@ class DynamicPanel extends StatelessWidget {
|
||||
return;
|
||||
}
|
||||
imageSaveDialog(
|
||||
context: context,
|
||||
title: title,
|
||||
cover: cover,
|
||||
);
|
||||
|
||||
@@ -19,7 +19,10 @@ import 'pic_panel.dart';
|
||||
import 'rich_node_panel.dart';
|
||||
import 'video_panel.dart';
|
||||
|
||||
InlineSpan picsNodes(List<OpusPicsModel> pics, callback) {
|
||||
InlineSpan picsNodes(
|
||||
List<OpusPicsModel> pics,
|
||||
Function(List<String>, int)? callback,
|
||||
) {
|
||||
return WidgetSpan(
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) => imageView(
|
||||
@@ -40,7 +43,7 @@ InlineSpan picsNodes(List<OpusPicsModel> pics, callback) {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _blockedItem(BuildContext context, DynamicItemModel item, source) {
|
||||
Widget _blockedItem(ThemeData theme, DynamicItemModel item, String? source) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(
|
||||
@@ -53,7 +56,7 @@ Widget _blockedItem(BuildContext context, DynamicItemModel item, source) {
|
||||
Text(
|
||||
item.modules.moduleDynamic!.major!.blocked!['title'],
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
if (item.modules.moduleDynamic!.major!.blocked!['hint_message'] != null)
|
||||
@@ -61,7 +64,7 @@ Widget _blockedItem(BuildContext context, DynamicItemModel item, source) {
|
||||
item.modules.moduleDynamic!.major!.blocked!['hint_message'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -70,15 +73,21 @@ Widget _blockedItem(BuildContext context, DynamicItemModel item, source) {
|
||||
}
|
||||
|
||||
Widget forWard(
|
||||
bool isSave, DynamicItemModel item, BuildContext context, source, callback,
|
||||
{floor = 1}) {
|
||||
ThemeData theme,
|
||||
bool isSave,
|
||||
DynamicItemModel item,
|
||||
BuildContext context,
|
||||
source,
|
||||
callback, {
|
||||
floor = 1,
|
||||
}) {
|
||||
switch (item.type) {
|
||||
// 图文
|
||||
case 'DYNAMIC_TYPE_DRAW':
|
||||
bool hasPics =
|
||||
item.modules.moduleDynamic?.major?.opus?.pics?.isNotEmpty == true;
|
||||
|
||||
InlineSpan? richNodes = richNode(item, context);
|
||||
TextSpan? richNodes = richNode(theme, item, context);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -91,17 +100,15 @@ Widget forWard(
|
||||
arguments: {'face': item.modules.moduleAuthor!.face}),
|
||||
child: Text(
|
||||
'@${item.modules.moduleAuthor!.name}',
|
||||
style:
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary),
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
Utils.dateFormat(item.modules.moduleAuthor!.pubTs),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelSmall!.fontSize),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -139,22 +146,24 @@ Widget forWard(
|
||||
/// 附加内容 商品信息、直播预约等等
|
||||
if (item.modules.moduleDynamic?.additional != null)
|
||||
addWidget(
|
||||
theme,
|
||||
item,
|
||||
context,
|
||||
item.modules.moduleDynamic?.additional?.type,
|
||||
floor: floor,
|
||||
),
|
||||
if (item.modules.moduleDynamic?.major?.blocked != null)
|
||||
_blockedItem(context, item, source),
|
||||
_blockedItem(theme, item, source),
|
||||
],
|
||||
);
|
||||
// 视频
|
||||
case 'DYNAMIC_TYPE_AV':
|
||||
return videoSeasonWidget(source, item, context, 'archive', floor: floor);
|
||||
return videoSeasonWidget(theme, source, item, context, 'archive',
|
||||
floor: floor);
|
||||
// 文章
|
||||
case 'DYNAMIC_TYPE_ARTICLE':
|
||||
return item.isForwarded == true
|
||||
? articlePanel(source, item, context, callback, floor: floor)
|
||||
? articlePanel(theme, source, item, context, callback, floor: floor)
|
||||
: item.modules.moduleDynamic?.major?.blocked != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
@@ -168,7 +177,7 @@ Widget forWard(
|
||||
Text(
|
||||
item.modules.moduleDynamic!.major!.blocked!['title'],
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
if (item.modules.moduleDynamic?.major
|
||||
@@ -179,7 +188,7 @@ Widget forWard(
|
||||
.blocked!['hint_message'],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
)
|
||||
],
|
||||
@@ -225,29 +234,28 @@ Widget forWard(
|
||||
return;
|
||||
}
|
||||
imageSaveDialog(
|
||||
context: context,
|
||||
title: title,
|
||||
cover: cover,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8),
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.08),
|
||||
child: forWard(isSave, item.orig!, context, source, callback,
|
||||
color: theme.dividerColor.withOpacity(0.08),
|
||||
child: forWard(theme, isSave, item.orig!, context, source, callback,
|
||||
floor: floor + 1),
|
||||
),
|
||||
);
|
||||
// 直播
|
||||
case 'DYNAMIC_TYPE_LIVE_RCMD':
|
||||
return liveRcmdPanel(source, item, context, floor: floor);
|
||||
return liveRcmdPanel(theme, source, item, context, floor: floor);
|
||||
// 直播
|
||||
case 'DYNAMIC_TYPE_LIVE':
|
||||
return livePanel(source, item, context, floor: floor);
|
||||
return livePanel(theme, source, item, context, floor: floor);
|
||||
// 合集
|
||||
case 'DYNAMIC_TYPE_UGC_SEASON':
|
||||
return videoSeasonWidget(source, item, context, 'ugcSeason');
|
||||
return videoSeasonWidget(theme, source, item, context, 'ugcSeason');
|
||||
case 'DYNAMIC_TYPE_WORD':
|
||||
InlineSpan? richNodes = richNode(item, context);
|
||||
late TextSpan? richNodes = richNode(theme, item, context);
|
||||
return floor == 2
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -260,17 +268,15 @@ Widget forWard(
|
||||
arguments: {'face': item.modules.moduleAuthor?.face}),
|
||||
child: Text(
|
||||
'@${item.modules.moduleAuthor?.name}',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary),
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
Utils.dateFormat(item.modules.moduleAuthor?.pubTs),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelSmall!.fontSize),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -294,18 +300,21 @@ Widget forWard(
|
||||
)
|
||||
: item.modules.moduleDynamic?.additional != null
|
||||
? addWidget(
|
||||
theme,
|
||||
item,
|
||||
context,
|
||||
item.modules.moduleDynamic!.additional!.type,
|
||||
floor: floor,
|
||||
)
|
||||
: item.modules.moduleDynamic?.major?.blocked != null
|
||||
? _blockedItem(context, item, source)
|
||||
? _blockedItem(theme, item, source)
|
||||
: const SizedBox(height: 0);
|
||||
case 'DYNAMIC_TYPE_PGC':
|
||||
return videoSeasonWidget(source, item, context, 'pgc', floor: floor);
|
||||
return videoSeasonWidget(theme, source, item, context, 'pgc',
|
||||
floor: floor);
|
||||
case 'DYNAMIC_TYPE_PGC_UNION':
|
||||
return videoSeasonWidget(source, item, context, 'pgc', floor: floor);
|
||||
return videoSeasonWidget(theme, source, item, context, 'pgc',
|
||||
floor: floor);
|
||||
// 直播结束
|
||||
case 'DYNAMIC_TYPE_NONE':
|
||||
return Row(
|
||||
@@ -347,7 +356,7 @@ Widget forWard(
|
||||
width: double.infinity,
|
||||
padding:
|
||||
const EdgeInsets.only(left: 12, top: 10, right: 12, bottom: 10),
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.08),
|
||||
color: theme.dividerColor.withOpacity(0.08),
|
||||
child: Row(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
@@ -365,7 +374,7 @@ Widget forWard(
|
||||
Text(
|
||||
item.modules.moduleDynamic!.major!.common!['title'],
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -374,9 +383,8 @@ Widget forWard(
|
||||
Text(
|
||||
item.modules.moduleDynamic!.major!.common!['desc'],
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -398,7 +406,7 @@ Widget forWard(
|
||||
width: double.infinity,
|
||||
padding:
|
||||
const EdgeInsets.only(left: 12, top: 10, right: 12, bottom: 10),
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.08),
|
||||
color: theme.dividerColor.withOpacity(0.08),
|
||||
child: Row(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
@@ -415,7 +423,7 @@ Widget forWard(
|
||||
Text(
|
||||
music['title'],
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -424,9 +432,8 @@ Widget forWard(
|
||||
Text(
|
||||
music['label'],
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -464,9 +471,8 @@ Widget forWard(
|
||||
item.modules.moduleAuthor!.vip!['status'] > 0 &&
|
||||
item.modules.moduleAuthor!.vip!['type'] == 2
|
||||
? context.vipColor
|
||||
: Theme.of(context).colorScheme.onSurface,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.titleMedium!.fontSize,
|
||||
: theme.colorScheme.onSurface,
|
||||
fontSize: theme.textTheme.titleMedium!.fontSize,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -510,10 +516,7 @@ Widget forWard(
|
||||
Text(
|
||||
item.modules.moduleDynamic!.major!.medialist!['title'],
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.fontSize,
|
||||
fontSize: theme.textTheme.titleMedium!.fontSize,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
if (item.modules.moduleDynamic?.major
|
||||
@@ -524,11 +527,8 @@ Widget forWard(
|
||||
item.modules.moduleDynamic!.major!
|
||||
.medialist!['sub_title'],
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelLarge!
|
||||
.fontSize,
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
fontSize: theme.textTheme.labelLarge!.fontSize,
|
||||
color: theme.colorScheme.outline),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||
@@ -6,11 +7,19 @@ import 'package:PiliPlus/utils/utils.dart';
|
||||
|
||||
import 'rich_node_panel.dart';
|
||||
|
||||
Widget livePanel(source, item, context, {floor = 1}) {
|
||||
dynamic content = item.modules.moduleDynamic.major;
|
||||
late final TextStyle authorStyle =
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary);
|
||||
InlineSpan? richNodes = richNode(item, context);
|
||||
Widget livePanel(
|
||||
ThemeData theme,
|
||||
String? source,
|
||||
DynamicItemModel item,
|
||||
BuildContext context, {
|
||||
int floor = 1,
|
||||
}) {
|
||||
DynamicMajorModel? content = item.modules.moduleDynamic!.major;
|
||||
if (content == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
late final authorStyle = TextStyle(color: theme.colorScheme.primary);
|
||||
TextSpan? richNodes = richNode(theme, item, context);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -19,40 +28,41 @@ Widget livePanel(source, item, context, {floor = 1}) {
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => Get.toNamed(
|
||||
'/member?mid=${item.modules.moduleAuthor.mid}',
|
||||
arguments: {'face': item.modules.moduleAuthor.face}),
|
||||
'/member?mid=${item.modules.moduleAuthor!.mid}',
|
||||
arguments: {'face': item.modules.moduleAuthor!.face}),
|
||||
child: Text(
|
||||
'@${item.modules.moduleAuthor.name}',
|
||||
'@${item.modules.moduleAuthor!.name}',
|
||||
style: authorStyle,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
Utils.dateFormat(item.modules.moduleAuthor.pubTs),
|
||||
Utils.dateFormat(item.modules.moduleAuthor?.pubTs),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize: Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelSmall!.fontSize,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 4),
|
||||
if (item.modules.moduleDynamic.topic != null) ...[
|
||||
if (item.modules.moduleDynamic?.topic != null) ...[
|
||||
Padding(
|
||||
padding: floor == 2
|
||||
? EdgeInsets.zero
|
||||
: const EdgeInsets.only(left: 12, right: 12),
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
'#${item.modules.moduleDynamic.topic.name}',
|
||||
style: authorStyle,
|
||||
),
|
||||
child: Text(
|
||||
'#${item.modules.moduleDynamic!.topic!.name}',
|
||||
style: authorStyle,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
if (floor == 2 && item.modules.moduleDynamic.desc != null) ...[
|
||||
if (richNodes != null) Text.rich(richNodes),
|
||||
if (floor == 2 &&
|
||||
item.modules.moduleDynamic?.desc != null &&
|
||||
richNodes != null) ...[
|
||||
Text.rich(richNodes),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
GestureDetector(
|
||||
@@ -63,9 +73,8 @@ Widget livePanel(source, item, context, {floor = 1}) {
|
||||
onLongPress: () {
|
||||
Feedback.forLongPress(context);
|
||||
imageSaveDialog(
|
||||
context: context,
|
||||
title: content.live.title,
|
||||
cover: content.live.cover,
|
||||
title: content.live!.title,
|
||||
cover: content.live!.cover,
|
||||
);
|
||||
},
|
||||
child: Row(
|
||||
@@ -75,7 +84,7 @@ Widget livePanel(source, item, context, {floor = 1}) {
|
||||
NetworkImgLayer(
|
||||
width: 120,
|
||||
height: 75,
|
||||
src: content.live.cover,
|
||||
src: content.live!.cover,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
@@ -84,26 +93,26 @@ Widget livePanel(source, item, context, {floor = 1}) {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
content.live.title,
|
||||
content.live!.title!,
|
||||
maxLines: source == 'detail' ? null : 2,
|
||||
overflow: source == 'detail' ? null : TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
content.live.descFirst,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
)
|
||||
if (content.live?.descFirst != null)
|
||||
Text(
|
||||
content.live!.descFirst!,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
content.live.badge['text'],
|
||||
content.live!.badge!['text'],
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
)
|
||||
],
|
||||
|
||||
@@ -9,13 +9,21 @@ import 'package:PiliPlus/utils/utils.dart';
|
||||
|
||||
import 'rich_node_panel.dart';
|
||||
|
||||
Widget liveRcmdPanel(source, DynamicItemModel item, context, {floor = 1}) {
|
||||
TextStyle authorStyle =
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary);
|
||||
DynamicLiveModel liveRcmd = item.modules.moduleDynamic!.major!.liveRcmd!;
|
||||
int liveStatus = liveRcmd.liveStatus!;
|
||||
Map watchedShow = liveRcmd.watchedShow!;
|
||||
InlineSpan? richNodes = richNode(item, context);
|
||||
Widget liveRcmdPanel(
|
||||
ThemeData theme,
|
||||
String? source,
|
||||
DynamicItemModel item,
|
||||
BuildContext context, {
|
||||
int floor = 1,
|
||||
}) {
|
||||
DynamicLiveModel? liveRcmd = item.modules.moduleDynamic?.major?.liveRcmd;
|
||||
if (liveRcmd == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
int? liveStatus = liveRcmd.liveStatus;
|
||||
Map? watchedShow = liveRcmd.watchedShow;
|
||||
TextSpan? richNodes = richNode(theme, item, context);
|
||||
late final authorStyle = TextStyle(color: theme.colorScheme.primary);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -24,8 +32,9 @@ Widget liveRcmdPanel(source, DynamicItemModel item, context, {floor = 1}) {
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => Get.toNamed(
|
||||
'/member?mid=${item.modules.moduleAuthor?.mid}',
|
||||
arguments: {'face': item.modules.moduleAuthor?.face}),
|
||||
'/member?mid=${item.modules.moduleAuthor?.mid}',
|
||||
arguments: {'face': item.modules.moduleAuthor?.face},
|
||||
),
|
||||
child: Text(
|
||||
'@${item.modules.moduleAuthor?.name}',
|
||||
style: authorStyle,
|
||||
@@ -35,8 +44,9 @@ Widget liveRcmdPanel(source, DynamicItemModel item, context, {floor = 1}) {
|
||||
Text(
|
||||
Utils.dateFormat(item.modules.moduleAuthor?.pubTs),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize: Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelSmall!.fontSize,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -46,27 +56,27 @@ Widget liveRcmdPanel(source, DynamicItemModel item, context, {floor = 1}) {
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: GestureDetector(
|
||||
child: Text(
|
||||
'#${item.modules.moduleDynamic!.topic!.name}',
|
||||
style: authorStyle,
|
||||
),
|
||||
child: Text(
|
||||
'#${item.modules.moduleDynamic!.topic!.name}',
|
||||
style: authorStyle,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
if (floor == 2 && item.modules.moduleDynamic?.desc != null) ...[
|
||||
if (richNodes != null) Text.rich(richNodes),
|
||||
if (floor == 2 &&
|
||||
item.modules.moduleDynamic?.desc != null &&
|
||||
richNodes != null) ...[
|
||||
Text.rich(richNodes),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
PageUtils.pushDynDetail(item, floor);
|
||||
},
|
||||
child: LayoutBuilder(builder: (context, box) {
|
||||
padding: const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
PageUtils.pushDynDetail(item, floor);
|
||||
},
|
||||
child: LayoutBuilder(
|
||||
builder: (context, box) {
|
||||
double width = box.maxWidth;
|
||||
return Stack(
|
||||
children: [
|
||||
@@ -75,33 +85,31 @@ Widget liveRcmdPanel(source, DynamicItemModel item, context, {floor = 1}) {
|
||||
child: NetworkImgLayer(
|
||||
width: width,
|
||||
height: width / StyleString.aspectRatio,
|
||||
src: item.modules.moduleDynamic?.major?.liveRcmd?.cover,
|
||||
src: liveRcmd.cover,
|
||||
),
|
||||
),
|
||||
PBadge(
|
||||
text: watchedShow['text_large'],
|
||||
text: watchedShow?['text_large'],
|
||||
top: 6,
|
||||
right: 56,
|
||||
bottom: null,
|
||||
left: null,
|
||||
type: 'gray',
|
||||
),
|
||||
PBadge(
|
||||
text: liveStatus == 1 ? '直播中' : '直播结束',
|
||||
top: 6,
|
||||
right: 6,
|
||||
bottom: null,
|
||||
left: null,
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
height: 80,
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 10, 10),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
if (liveRcmd.areaName != null)
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
height: 80,
|
||||
alignment: Alignment.bottomLeft,
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 10, 10),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
@@ -111,45 +119,42 @@ Widget liveRcmdPanel(source, DynamicItemModel item, context, {floor = 1}) {
|
||||
],
|
||||
),
|
||||
borderRadius: floor == 1
|
||||
? StyleString.mdRadius
|
||||
: const BorderRadius.all(Radius.circular(6))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
DefaultTextStyle.merge(
|
||||
style: TextStyle(
|
||||
fontSize: Theme.of(context)
|
||||
.textTheme
|
||||
.labelMedium!
|
||||
.fontSize,
|
||||
color: Colors.white),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(item.modules.moduleDynamic?.major?.liveRcmd
|
||||
?.areaName ??
|
||||
''),
|
||||
],
|
||||
),
|
||||
? const BorderRadius.only(
|
||||
bottomLeft: StyleString.imgRadius,
|
||||
bottomRight: StyleString.imgRadius,
|
||||
)
|
||||
: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(6),
|
||||
bottomRight: Radius.circular(6),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
liveRcmd.areaName!,
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
)),
|
||||
const SizedBox(height: 6),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: Text(
|
||||
item.modules.moduleDynamic!.major!.liveRcmd!.title!,
|
||||
maxLines: source == 'detail' ? null : 1,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
overflow: source == 'detail' ? null : TextOverflow.ellipsis,
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
if (liveRcmd.title != null)
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: Text(
|
||||
liveRcmd.title!,
|
||||
maxLines: source == 'detail' ? null : 1,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
overflow: source == 'detail' ? null : TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import 'package:PiliPlus/common/widgets/image_view.dart';
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Widget picWidget(item, context, callback) {
|
||||
if (item.modules.moduleDynamic.major?.draw?.items == null ||
|
||||
item.modules.moduleDynamic.major.type == 'MAJOR_TYPE_OPUS') {
|
||||
Widget picWidget(
|
||||
DynamicItemModel item,
|
||||
BuildContext context,
|
||||
Function(List<String>, int)? callback,
|
||||
) {
|
||||
if (item.modules.moduleDynamic?.major?.draw?.items == null ||
|
||||
item.modules.moduleDynamic?.major?.type == 'MAJOR_TYPE_OPUS') {
|
||||
/// fix 图片跟rich_node_panel重复
|
||||
// pictures = item.modules.moduleDynamic.major.opus.pics;
|
||||
return const SizedBox.shrink();
|
||||
@@ -11,7 +16,7 @@ Widget picWidget(item, context, callback) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) => imageView(
|
||||
constraints.maxWidth,
|
||||
(item.modules.moduleDynamic.major.draw.items as List)
|
||||
(item.modules.moduleDynamic!.major!.draw!.items as List)
|
||||
.map(
|
||||
(item) => ImageModel(
|
||||
width: item.width,
|
||||
|
||||
@@ -10,27 +10,27 @@ import 'package:PiliPlus/http/search.dart';
|
||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||
|
||||
// 富文本
|
||||
InlineSpan? richNode(item, BuildContext context) {
|
||||
final spacer = _VerticalSpaceSpan(0.0);
|
||||
TextSpan? richNode(
|
||||
ThemeData theme,
|
||||
DynamicItemModel item,
|
||||
BuildContext context,
|
||||
) {
|
||||
try {
|
||||
TextStyle authorStyle =
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary);
|
||||
late final authorStyle = TextStyle(color: theme.colorScheme.primary);
|
||||
List<InlineSpan> spanChildren = [];
|
||||
|
||||
List<RichTextNodeItem>? richTextNodes;
|
||||
if (item.modules.moduleDynamic.desc != null) {
|
||||
richTextNodes = item.modules.moduleDynamic.desc.richTextNodes;
|
||||
} else if (item.modules.moduleDynamic.major != null) {
|
||||
if (item.modules.moduleDynamic?.desc != null) {
|
||||
richTextNodes = item.modules.moduleDynamic!.desc!.richTextNodes;
|
||||
} else if (item.modules.moduleDynamic?.major != null) {
|
||||
// 动态页面 richTextNodes 层级可能与主页动态层级不同
|
||||
richTextNodes =
|
||||
item.modules.moduleDynamic.major.opus?.summary?.richTextNodes;
|
||||
if (item.modules.moduleDynamic.major.opus?.title != null) {
|
||||
item.modules.moduleDynamic!.major!.opus?.summary?.richTextNodes;
|
||||
if (item.modules.moduleDynamic?.major?.opus?.title != null) {
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
text: item.modules.moduleDynamic.major.opus.title + '\n',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
text: '${item.modules.moduleDynamic!.major!.opus!.title!}\n',
|
||||
style: theme.textTheme.titleMedium!
|
||||
.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
);
|
||||
@@ -42,7 +42,8 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
for (var i in richTextNodes) {
|
||||
if (i.type == 'RICH_TEXT_NODE_TYPE_TEXT') {
|
||||
spanChildren.add(
|
||||
TextSpan(text: i.origText, style: const TextStyle(height: 1.65)));
|
||||
TextSpan(text: i.origText, style: const TextStyle(height: 1.65)),
|
||||
);
|
||||
}
|
||||
// @用户
|
||||
else if (i.type == 'RICH_TEXT_NODE_TYPE_AT') {
|
||||
@@ -53,8 +54,7 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => Get.toNamed('/member?mid=${i.rid}',
|
||||
arguments: {'face': null}),
|
||||
onTap: () => Get.toNamed('/member?mid=${i.rid}'),
|
||||
child: Text(
|
||||
' ${i.text}',
|
||||
style: authorStyle,
|
||||
@@ -88,7 +88,7 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
child: Icon(
|
||||
Icons.link,
|
||||
size: 20,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -120,14 +120,12 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
try {
|
||||
String dynamicId = item.basic.commentIdStr;
|
||||
String dynamicId = item.basic!.commentIdStr!;
|
||||
Get.toNamed(
|
||||
'/webview',
|
||||
parameters: {
|
||||
'url':
|
||||
'https://t.bilibili.com/vote/h5/index/#/result?vote_id=${i.rid}&dynamic_id=$dynamicId&isWeb=1',
|
||||
'type': 'vote',
|
||||
'pageTitle': '投票'
|
||||
},
|
||||
);
|
||||
} catch (_) {}
|
||||
@@ -161,7 +159,7 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
child: Icon(
|
||||
Icons.redeem_rounded,
|
||||
size: 16,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -195,7 +193,7 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
child: Icon(
|
||||
Icons.shopping_bag_outlined,
|
||||
size: 16,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -220,7 +218,7 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
child: Icon(
|
||||
Icons.play_circle_outline_outlined,
|
||||
size: 16,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -234,7 +232,6 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
PageUtils.toVideoPage(
|
||||
'bvid=${i.rid}&cid=$cid',
|
||||
arguments: {
|
||||
'pic': null,
|
||||
'heroTag': Utils.makeHeroTag(i.rid),
|
||||
},
|
||||
);
|
||||
@@ -285,11 +282,6 @@ InlineSpan? richNode(item, BuildContext context) {
|
||||
}
|
||||
} catch (err) {
|
||||
debugPrint('❌rich_node_panel err: $err');
|
||||
return spacer;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _VerticalSpaceSpan extends WidgetSpan {
|
||||
_VerticalSpaceSpan(double height)
|
||||
: super(child: SizedBox(height: height, width: double.infinity));
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
if (widget.dynamicsController.isLogin.value.not) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
@@ -74,14 +75,15 @@ class _UpPanelState extends State<UpPanel> {
|
||||
SliverList.builder(
|
||||
itemCount: liveList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return upItemBuild(liveList[index]);
|
||||
return upItemBuild(theme, liveList[index]);
|
||||
},
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: upItemBuild(UpItem(face: '', uname: '全部动态', mid: -1)),
|
||||
child: upItemBuild(theme, UpItem(face: '', uname: '全部动态', mid: -1)),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: upItemBuild(
|
||||
theme,
|
||||
UpItem(
|
||||
uname: '我',
|
||||
face: widget.dynamicsController.face,
|
||||
@@ -93,7 +95,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
SliverList.builder(
|
||||
itemCount: upList.length,
|
||||
itemBuilder: (context, index) {
|
||||
return upItemBuild(upList[index]);
|
||||
return upItemBuild(theme, upList[index]);
|
||||
},
|
||||
),
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 200)),
|
||||
@@ -101,7 +103,7 @@ class _UpPanelState extends State<UpPanel> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget upItemBuild(data) {
|
||||
Widget upItemBuild(theme, data) {
|
||||
bool isCurrent = widget.dynamicsController.currentMid == data.mid ||
|
||||
widget.dynamicsController.currentMid == -1;
|
||||
return SizedBox(
|
||||
@@ -163,17 +165,14 @@ class _UpPanelState extends State<UpPanel> {
|
||||
child: Badge(
|
||||
smallSize: 8,
|
||||
label: data.type == 'live' ? const Text(' Live ') : null,
|
||||
textColor:
|
||||
Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
textColor: theme.colorScheme.onSecondaryContainer,
|
||||
alignment: AlignmentDirectional.topStart,
|
||||
isLabelVisible: data.type == 'live' ||
|
||||
(data.type == 'up' && (data.hasUpdate ?? false)),
|
||||
backgroundColor: data.type == 'live'
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.secondaryContainer
|
||||
? theme.colorScheme.secondaryContainer
|
||||
.withOpacity(0.75)
|
||||
: Theme.of(context).colorScheme.primary,
|
||||
: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -189,8 +188,8 @@ class _UpPanelState extends State<UpPanel> {
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: widget.dynamicsController.currentMid == data.mid
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).colorScheme.outline,
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.outline,
|
||||
height: 1.1,
|
||||
fontSize: 12.5,
|
||||
),
|
||||
@@ -203,31 +202,3 @@ class _UpPanelState extends State<UpPanel> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class UpPanelSkeleton extends StatelessWidget {
|
||||
const UpPanelSkeleton({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 6),
|
||||
width: 45,
|
||||
height: 12,
|
||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// 视频or合集
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
@@ -8,21 +9,28 @@ import 'package:PiliPlus/utils/utils.dart';
|
||||
|
||||
import 'rich_node_panel.dart';
|
||||
|
||||
Widget videoSeasonWidget(source, item, context, type, {floor = 1}) {
|
||||
if (item.modules.moduleDynamic.major?.type == 'MAJOR_TYPE_NONE') {
|
||||
return item.modules.moduleDynamic.major?.none?.tips != null
|
||||
Widget videoSeasonWidget(
|
||||
ThemeData theme,
|
||||
String? source,
|
||||
DynamicItemModel item,
|
||||
BuildContext context,
|
||||
String type, {
|
||||
floor = 1,
|
||||
}) {
|
||||
if (item.modules.moduleDynamic?.major?.type == 'MAJOR_TYPE_NONE') {
|
||||
return item.modules.moduleDynamic?.major?.none?.tips != null
|
||||
? Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.error,
|
||||
size: 18,
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'${item.modules.moduleDynamic.major.none.tips}',
|
||||
item.modules.moduleDynamic!.major!.none!.tips!,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -30,8 +38,6 @@ Widget videoSeasonWidget(source, item, context, type, {floor = 1}) {
|
||||
: const SizedBox.shrink();
|
||||
}
|
||||
|
||||
TextStyle authorStyle =
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary);
|
||||
// type archive ugcSeason
|
||||
// archive 视频/显示发布人
|
||||
// ugcSeason 合集/不显示发布人
|
||||
@@ -39,93 +45,97 @@ Widget videoSeasonWidget(source, item, context, type, {floor = 1}) {
|
||||
// floor 1 2
|
||||
// 1 投稿视频 铺满 borderRadius 0
|
||||
// 2 转发视频 铺满 borderRadius 6
|
||||
Map<dynamic, dynamic> dynamicProperty = {
|
||||
'ugcSeason': item.modules.moduleDynamic.major.ugcSeason,
|
||||
'archive': item.modules.moduleDynamic.major.archive,
|
||||
'pgc': item.modules.moduleDynamic.major.pgc
|
||||
|
||||
DynamicArchiveModel? content = switch (type) {
|
||||
'ugcSeason' => item.modules.moduleDynamic?.major?.ugcSeason,
|
||||
'archive' => item.modules.moduleDynamic?.major?.archive,
|
||||
'pgc' => item.modules.moduleDynamic?.major?.pgc,
|
||||
_ => null,
|
||||
};
|
||||
dynamic content = dynamicProperty[type];
|
||||
InlineSpan? richNodes = richNode(item, context);
|
||||
|
||||
if (content == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
TextSpan? richNodes = richNode(theme, item, context);
|
||||
|
||||
Widget buildCover() {
|
||||
if (content?.cover == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return LayoutBuilder(builder: (context, box) {
|
||||
double width = box.maxWidth;
|
||||
return Stack(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
width: width,
|
||||
height: width / StyleString.aspectRatio,
|
||||
src: content.cover,
|
||||
semanticsLabel: content.title,
|
||||
),
|
||||
if (content?.badge?['text'] != null)
|
||||
PBadge(
|
||||
text: content.badge['text'],
|
||||
top: 8.0,
|
||||
right: 10.0,
|
||||
bottom: null,
|
||||
left: null,
|
||||
type: content.badge['text'] == '充电专属' ? 'error' : 'primary',
|
||||
return LayoutBuilder(
|
||||
builder: (context, box) {
|
||||
double width = box.maxWidth;
|
||||
return Stack(
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
width: width,
|
||||
height: width / StyleString.aspectRatio,
|
||||
src: content.cover,
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
height: 70,
|
||||
padding: const EdgeInsets.fromLTRB(10, 0, 8, 8),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: <Color>[
|
||||
Colors.transparent,
|
||||
Colors.black54,
|
||||
],
|
||||
if (content.badge?['text'] != null)
|
||||
PBadge(
|
||||
text: content.badge!['text'],
|
||||
top: 8.0,
|
||||
right: 10.0,
|
||||
bottom: null,
|
||||
left: null,
|
||||
type: content.badge!['text'] == '充电专属' ? 'error' : 'primary',
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
height: 70,
|
||||
alignment: Alignment.bottomLeft,
|
||||
padding: const EdgeInsets.fromLTRB(10, 0, 8, 8),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.transparent,
|
||||
Colors.black54,
|
||||
],
|
||||
),
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: StyleString.imgRadius,
|
||||
bottomRight: StyleString.imgRadius,
|
||||
),
|
||||
),
|
||||
borderRadius: StyleString.mdRadius,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
DefaultTextStyle.merge(
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||
color: Colors.white),
|
||||
child: Row(
|
||||
children: [
|
||||
if (content.durationText != null)
|
||||
Text(
|
||||
content.durationText,
|
||||
semanticsLabel:
|
||||
'时长${Utils.durationReadFormat(content.durationText)}',
|
||||
),
|
||||
if (content.durationText != null)
|
||||
const SizedBox(width: 6),
|
||||
Text(content.stat.play + '次围观'),
|
||||
child: DefaultTextStyle.merge(
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (content.durationText != null) ...[
|
||||
Text(
|
||||
content.durationText!,
|
||||
semanticsLabel:
|
||||
'时长${Utils.durationReadFormat(content.durationText!)}',
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(content.stat.danmu + '条弹幕')
|
||||
],
|
||||
),
|
||||
Text('${content.stat?.play}次围观'),
|
||||
const SizedBox(width: 6),
|
||||
Text('${content.stat?.danmu}条弹幕'),
|
||||
const Spacer(),
|
||||
Image.asset(
|
||||
'assets/images/play.png',
|
||||
width: 50,
|
||||
height: 50,
|
||||
),
|
||||
],
|
||||
),
|
||||
Image.asset(
|
||||
'assets/images/play.png',
|
||||
width: 50,
|
||||
height: 50,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
@@ -137,45 +147,50 @@ Widget videoSeasonWidget(source, item, context, type, {floor = 1}) {
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => Get.toNamed(
|
||||
'/member?mid=${item.modules.moduleAuthor.mid}',
|
||||
arguments: {'face': item.modules.moduleAuthor.face}),
|
||||
'/member?mid=${item.modules.moduleAuthor!.mid}',
|
||||
arguments: {'face': item.modules.moduleAuthor!.face},
|
||||
),
|
||||
child: Text(
|
||||
item.modules.moduleAuthor.type == null
|
||||
? '@${item.modules.moduleAuthor.name}'
|
||||
: item.modules.moduleAuthor.name,
|
||||
style: authorStyle,
|
||||
item.modules.moduleAuthor?.type == null
|
||||
? '@${item.modules.moduleAuthor!.name}'
|
||||
: item.modules.moduleAuthor!.name!,
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
Utils.dateFormat(item.modules.moduleAuthor.pubTs),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
fontSize: Theme.of(context).textTheme.labelSmall!.fontSize),
|
||||
),
|
||||
if (item.modules.moduleAuthor?.pubTs != null)
|
||||
Text(
|
||||
Utils.dateFormat(item.modules.moduleAuthor!.pubTs),
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.outline,
|
||||
fontSize: theme.textTheme.labelSmall!.fontSize,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
if (floor == 2 && item.modules.moduleDynamic.desc != null) ...[
|
||||
if (richNodes != null) Text.rich(richNodes),
|
||||
if (floor == 2 && content.desc != null && richNodes != null) ...[
|
||||
Text.rich(richNodes),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
if (item.isForwarded == true)
|
||||
buildCover()
|
||||
else
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: buildCover(),
|
||||
),
|
||||
if (content.cover != null)
|
||||
if (item.isForwarded == true)
|
||||
buildCover()
|
||||
else
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
child: buildCover(),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
if (content?.title != null)
|
||||
if (content.title != null)
|
||||
Padding(
|
||||
padding: floor == 1
|
||||
? const EdgeInsets.only(left: 12, right: 12)
|
||||
: EdgeInsets.zero,
|
||||
child: Text(
|
||||
content.title,
|
||||
content.title!,
|
||||
maxLines: source == 'detail' ? null : 1,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
overflow: source == 'detail' ? null : TextOverflow.ellipsis,
|
||||
|
||||
Reference in New Issue
Block a user