mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-08 03:54:49 +08:00
@@ -1,14 +1,11 @@
|
||||
import 'package:PiliPlus/common/style.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/image_save.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/select_mask.dart';
|
||||
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/app/listener/v1.pbenum.dart'
|
||||
show PlaylistSource;
|
||||
import 'package:PiliPlus/models/common/badge_type.dart';
|
||||
import 'package:PiliPlus/models/common/stat_type.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_detail/media.dart';
|
||||
import 'package:PiliPlus/pages/audio/view.dart';
|
||||
import 'package:PiliPlus/pages/fav_detail/controller.dart';
|
||||
@@ -18,6 +15,7 @@ import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
// 收藏视频卡片 - 水平布局
|
||||
class FavVideoCardH extends StatelessWidget {
|
||||
@@ -55,7 +53,7 @@ class FavVideoCardH extends StatelessWidget {
|
||||
);
|
||||
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
type: .transparency,
|
||||
child: InkWell(
|
||||
onTap: isSort
|
||||
? null
|
||||
@@ -89,12 +87,9 @@ class FavVideoCardH extends StatelessWidget {
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: Style.safeSpace,
|
||||
vertical: 5,
|
||||
),
|
||||
padding: const .symmetric(horizontal: Style.safeSpace, vertical: 5),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
@@ -103,7 +98,7 @@ class FavVideoCardH extends StatelessWidget {
|
||||
double maxWidth = boxConstraints.maxWidth;
|
||||
double maxHeight = boxConstraints.maxHeight;
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: item.cover,
|
||||
@@ -114,14 +109,14 @@ class FavVideoCardH extends StatelessWidget {
|
||||
text: DurationUtils.formatDuration(item.duration),
|
||||
right: 6.0,
|
||||
bottom: 6.0,
|
||||
type: PBadgeType.gray,
|
||||
type: .gray,
|
||||
),
|
||||
if (item.type == 12)
|
||||
const PBadge(
|
||||
text: '音频',
|
||||
top: 6.0,
|
||||
right: 6.0,
|
||||
type: PBadgeType.gray,
|
||||
type: .gray,
|
||||
)
|
||||
else
|
||||
PBadge(
|
||||
@@ -133,10 +128,7 @@ class FavVideoCardH extends StatelessWidget {
|
||||
),
|
||||
if (!isSort)
|
||||
Positioned.fill(
|
||||
child: selectMask(
|
||||
colorScheme,
|
||||
item.checked,
|
||||
),
|
||||
child: selectMask(colorScheme, item.checked),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -155,26 +147,26 @@ class FavVideoCardH extends StatelessWidget {
|
||||
Widget content(BuildContext context, ColorScheme colorScheme, bool isOwner) {
|
||||
return Expanded(
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
Column(
|
||||
spacing: 3,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
Text(
|
||||
item.title!,
|
||||
textAlign: TextAlign.start,
|
||||
textAlign: .start,
|
||||
style: const TextStyle(
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
if (item.type == 24 && item.intro?.isNotEmpty == true)
|
||||
Text(
|
||||
item.intro!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: colorScheme.outline,
|
||||
@@ -184,7 +176,7 @@ class FavVideoCardH extends StatelessWidget {
|
||||
Text(
|
||||
'${DateFormatUtils.dateFormat(item.favTime)} ${item.upper?.name}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
fontSize: 12,
|
||||
@@ -196,11 +188,11 @@ class FavVideoCardH extends StatelessWidget {
|
||||
spacing: 8,
|
||||
children: [
|
||||
StatWidget(
|
||||
type: StatType.play,
|
||||
type: .play,
|
||||
value: item.cntInfo?.play,
|
||||
),
|
||||
StatWidget(
|
||||
type: StatType.danmaku,
|
||||
type: .danmaku,
|
||||
value: item.cntInfo?.danmaku,
|
||||
),
|
||||
],
|
||||
@@ -211,33 +203,66 @@ class FavVideoCardH extends StatelessWidget {
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: -8,
|
||||
child: iconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
tooltip: '取消收藏',
|
||||
iconColor: colorScheme.outline,
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('提示'),
|
||||
content: const Text('要取消收藏吗?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(color: colorScheme.outline),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
ctr!.onCancelFav(index!, item.id!, item.type!);
|
||||
},
|
||||
child: const Text('确定取消'),
|
||||
),
|
||||
],
|
||||
),
|
||||
width: 29,
|
||||
height: 29,
|
||||
child: PopupMenuButton(
|
||||
padding: .zero,
|
||||
tooltip: '功能菜单',
|
||||
icon: Icon(
|
||||
Icons.more_vert_outlined,
|
||||
color: colorScheme.outline,
|
||||
size: 18,
|
||||
),
|
||||
position: .under,
|
||||
itemBuilder: (_) => [
|
||||
PopupMenuItem(
|
||||
onTap: () => Get.toNamed('/member?mid=${item.upper?.mid}'),
|
||||
height: 38,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(MdiIcons.accountCircleOutline, size: 16),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'访问:${item.upper?.name}',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('提示'),
|
||||
content: const Text('要取消收藏吗?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(color: colorScheme.outline),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
ctr!.onCancelFav(index!, item.id!, item.type!);
|
||||
},
|
||||
child: const Text('确定取消'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
height: 38,
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.close_outlined, size: 16),
|
||||
SizedBox(width: 6),
|
||||
Text('取消收藏', style: TextStyle(fontSize: 13)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -68,10 +68,7 @@ class _HistoryPageState extends State<HistoryPage>
|
||||
controller: _historyController.scrollController,
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 7,
|
||||
bottom: padding.bottom + 100,
|
||||
),
|
||||
padding: .only(top: 7, bottom: padding.bottom + 100),
|
||||
sliver: Obx(
|
||||
() => _buildBody(_historyController.loadingState.value),
|
||||
),
|
||||
@@ -100,18 +97,16 @@ class _HistoryPageState extends State<HistoryPage>
|
||||
child: _buildAppBar,
|
||||
),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: padding.left,
|
||||
right: padding.right,
|
||||
),
|
||||
padding: .only(left: padding.left, right: padding.right),
|
||||
child: Obx(() {
|
||||
final tabs = _historyController.tabs;
|
||||
if (tabs.isEmpty) {
|
||||
return child;
|
||||
}
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
?_buildPauseTip,
|
||||
TabBar(
|
||||
controller: _historyController.tabController,
|
||||
onTap: (index) {
|
||||
@@ -158,7 +153,6 @@ class _HistoryPageState extends State<HistoryPage>
|
||||
|
||||
AppBar get _buildAppBar => AppBar(
|
||||
title: const Text('观看记录'),
|
||||
bottom: _buildPauseTip,
|
||||
actions: [
|
||||
IconButton(
|
||||
tooltip: '搜索',
|
||||
@@ -242,7 +236,7 @@ class _HistoryPageState extends State<HistoryPage>
|
||||
child: Container(
|
||||
height: 38,
|
||||
color: theme.secondaryContainer.withValues(alpha: 0.8),
|
||||
padding: const EdgeInsets.only(left: 16, right: 6),
|
||||
padding: const .only(left: 16, right: 6),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
@@ -255,7 +249,7 @@ class _HistoryPageState extends State<HistoryPage>
|
||||
TextSpan(
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
alignment: .middle,
|
||||
child: Icon(
|
||||
Icons.info_outline,
|
||||
size: 18,
|
||||
@@ -268,13 +262,10 @@ class _HistoryPageState extends State<HistoryPage>
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
behavior: .opaque,
|
||||
onTap: () => _historyController.baseCtr.onPauseHistory(context),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 6,
|
||||
horizontal: 10,
|
||||
),
|
||||
padding: const .symmetric(vertical: 6, horizontal: 10),
|
||||
child: Text(
|
||||
'点击开启',
|
||||
strutStyle: const StrutStyle(height: 1, leading: 0),
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:PiliPlus/common/widgets/progress_bar/video_progress_indicator.da
|
||||
import 'package:PiliPlus/common/widgets/select_mask.dart';
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
import 'package:PiliPlus/http/user.dart';
|
||||
import 'package:PiliPlus/models/common/badge_type.dart';
|
||||
import 'package:PiliPlus/models_new/history/list.dart';
|
||||
import 'package:PiliPlus/models_new/video/video_detail/dimension.dart';
|
||||
import 'package:PiliPlus/pages/common/multi_select/base.dart';
|
||||
@@ -47,7 +46,7 @@ class HistoryItem extends StatelessWidget {
|
||||
..onSelect(item);
|
||||
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
type: .transparency,
|
||||
child: InkWell(
|
||||
onTap: enableMultiSelect
|
||||
? () => ctr.onSelect(item)
|
||||
@@ -108,15 +107,15 @@ class HistoryItem extends StatelessWidget {
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
padding: const .symmetric(
|
||||
horizontal: Style.safeSpace,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
@@ -125,7 +124,7 @@ class HistoryItem extends StatelessWidget {
|
||||
double maxWidth = boxConstraints.maxWidth;
|
||||
double maxHeight = boxConstraints.maxHeight;
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: item.cover?.isNotEmpty == true
|
||||
@@ -141,14 +140,14 @@ class HistoryItem extends StatelessWidget {
|
||||
: '${DurationUtils.formatDuration(item.progress)}/${DurationUtils.formatDuration(item.duration)}',
|
||||
right: 6.0,
|
||||
bottom: 8.0,
|
||||
type: PBadgeType.gray,
|
||||
type: .gray,
|
||||
),
|
||||
if (item.isFav == 1)
|
||||
const PBadge(
|
||||
text: '已收藏',
|
||||
top: 6.0,
|
||||
right: 6.0,
|
||||
type: PBadgeType.gray,
|
||||
type: .gray,
|
||||
)
|
||||
else if (item.badge?.isNotEmpty == true)
|
||||
PBadge(
|
||||
@@ -156,8 +155,8 @@ class HistoryItem extends StatelessWidget {
|
||||
top: 6.0,
|
||||
right: 6.0,
|
||||
type: business == 'live' && item.liveStatus != 1
|
||||
? PBadgeType.gray
|
||||
: PBadgeType.primary,
|
||||
? .gray
|
||||
: .primary,
|
||||
),
|
||||
if (hasDuration &&
|
||||
item.progress != null &&
|
||||
@@ -197,14 +196,14 @@ class HistoryItem extends StatelessWidget {
|
||||
width: 29,
|
||||
height: 29,
|
||||
child: PopupMenuButton(
|
||||
padding: EdgeInsets.zero,
|
||||
padding: .zero,
|
||||
tooltip: '功能菜单',
|
||||
icon: Icon(
|
||||
Icons.more_vert_outlined,
|
||||
color: theme.colorScheme.outline,
|
||||
size: 18,
|
||||
),
|
||||
position: PopupMenuPosition.under,
|
||||
position: .under,
|
||||
itemBuilder: (_) => [
|
||||
if (item.authorMid != null &&
|
||||
item.authorName?.isNotEmpty == true)
|
||||
@@ -266,7 +265,7 @@ class HistoryItem extends StatelessWidget {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
spacing: 2,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
Text(
|
||||
item.title!,
|
||||
@@ -276,7 +275,7 @@ class HistoryItem extends StatelessWidget {
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: item.videos! > 1 ? 1 : 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
if (item.history.business == 'pgc' &&
|
||||
item.showTitle?.isNotEmpty == true)
|
||||
@@ -287,14 +286,14 @@ class HistoryItem extends StatelessWidget {
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
const Spacer(),
|
||||
if (item.authorName?.isNotEmpty == true)
|
||||
Text(
|
||||
item.authorName!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: theme.textTheme.labelMedium!.fontSize,
|
||||
color: theme.colorScheme.outline,
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import 'package:PiliPlus/common/style.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/progress_bar/video_progress_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/select_mask.dart';
|
||||
import 'package:PiliPlus/common/widgets/stat/stat.dart';
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
import 'package:PiliPlus/models/common/badge_type.dart';
|
||||
import 'package:PiliPlus/models/common/stat_type.dart';
|
||||
import 'package:PiliPlus/models_new/later/list.dart';
|
||||
import 'package:PiliPlus/pages/later/controller.dart';
|
||||
import 'package:PiliPlus/utils/duration_utils.dart';
|
||||
@@ -15,6 +12,9 @@ import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get_core/src/get_main.dart';
|
||||
import 'package:get/get_navigation/src/extension_navigation.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
// 视频卡片 - 水平布局
|
||||
class VideoCardHLater extends StatelessWidget {
|
||||
@@ -42,7 +42,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
..onSelect(videoItem);
|
||||
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
type: .transparency,
|
||||
child: InkWell(
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
@@ -81,8 +81,8 @@ class VideoCardHLater extends StatelessWidget {
|
||||
vertical: 5,
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
child: LayoutBuilder(
|
||||
@@ -91,7 +91,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
final double maxHeight = boxConstraints.maxHeight;
|
||||
num? progress = videoItem.progress;
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: videoItem.pic,
|
||||
@@ -104,7 +104,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
text: '充电专属',
|
||||
top: 6.0,
|
||||
right: 6.0,
|
||||
type: PBadgeType.error,
|
||||
type: .error,
|
||||
)
|
||||
else if (videoItem.rights?.isCooperation == 1)
|
||||
const PBadge(
|
||||
@@ -131,7 +131,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
: '${DurationUtils.formatDuration(progress)}/${DurationUtils.formatDuration(videoItem.duration)}',
|
||||
right: 6,
|
||||
bottom: 8,
|
||||
type: PBadgeType.gray,
|
||||
type: .gray,
|
||||
),
|
||||
Positioned(
|
||||
left: 0,
|
||||
@@ -153,7 +153,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
),
|
||||
right: 6.0,
|
||||
bottom: 6.0,
|
||||
type: PBadgeType.gray,
|
||||
type: .gray,
|
||||
),
|
||||
Positioned.fill(
|
||||
child: selectMask(
|
||||
@@ -178,15 +178,15 @@ class VideoCardHLater extends StatelessWidget {
|
||||
Widget content(BuildContext context, ThemeData theme) {
|
||||
final isPgc = videoItem.isPgc == true && videoItem.bangumi != null;
|
||||
Widget stat = StatWidget(
|
||||
type: StatType.play,
|
||||
type: .play,
|
||||
value: videoItem.stat?.view,
|
||||
);
|
||||
return Expanded(
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: isPgc
|
||||
? [
|
||||
Text(
|
||||
@@ -197,18 +197,18 @@ class VideoCardHLater extends StatelessWidget {
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
videoItem.subtitle!,
|
||||
textAlign: TextAlign.start,
|
||||
textAlign: .start,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
const Spacer(),
|
||||
stat,
|
||||
@@ -223,7 +223,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
@@ -233,7 +233,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
fontSize: 12,
|
||||
height: 1,
|
||||
color: theme.colorScheme.outline,
|
||||
overflow: TextOverflow.clip,
|
||||
overflow: .clip,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
@@ -242,7 +242,7 @@ class VideoCardHLater extends StatelessWidget {
|
||||
children: [
|
||||
stat,
|
||||
StatWidget(
|
||||
type: StatType.danmaku,
|
||||
type: .danmaku,
|
||||
value: videoItem.stat?.danmaku,
|
||||
),
|
||||
],
|
||||
@@ -252,11 +252,45 @@ class VideoCardHLater extends StatelessWidget {
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: -8,
|
||||
child: iconButton(
|
||||
tooltip: '移除',
|
||||
onPressed: () => ctr.toViewDel(context, index, videoItem.aid),
|
||||
icon: const Icon(Icons.clear),
|
||||
iconColor: theme.colorScheme.outline,
|
||||
width: 29,
|
||||
height: 29,
|
||||
child: PopupMenuButton(
|
||||
padding: .zero,
|
||||
tooltip: '功能菜单',
|
||||
icon: Icon(
|
||||
Icons.more_vert_outlined,
|
||||
color: theme.colorScheme.outline,
|
||||
size: 18,
|
||||
),
|
||||
position: .under,
|
||||
itemBuilder: (_) => [
|
||||
PopupMenuItem(
|
||||
onTap: () =>
|
||||
Get.toNamed('/member?mid=${videoItem.owner?.mid}'),
|
||||
height: 38,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(MdiIcons.accountCircleOutline, size: 16),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'访问:${videoItem.owner?.name}',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: () => ctr.toViewDel(context, index, videoItem.aid),
|
||||
height: 38,
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.close_outlined, size: 16),
|
||||
SizedBox(width: 6),
|
||||
Text('移除', style: TextStyle(fontSize: 13)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class SubItem extends StatelessWidget {
|
||||
final SubItemModel item;
|
||||
@@ -30,7 +31,7 @@ class SubItem extends StatelessWidget {
|
||||
cover: item.cover,
|
||||
);
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
type: .transparency,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
if (item.state == 1) {
|
||||
@@ -54,9 +55,9 @@ class SubItem extends StatelessWidget {
|
||||
onLongPress: onLongPress,
|
||||
onSecondaryTap: PlatformUtils.isMobile ? null : onLongPress,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
|
||||
padding: const .symmetric(horizontal: 12, vertical: 5),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: Style.aspectRatio,
|
||||
@@ -65,18 +66,14 @@ class SubItem extends StatelessWidget {
|
||||
double maxWidth = boxConstraints.maxWidth;
|
||||
double maxHeight = boxConstraints.maxHeight;
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
src: item.cover,
|
||||
width: maxWidth,
|
||||
height: maxHeight,
|
||||
),
|
||||
PBadge(
|
||||
right: 6,
|
||||
top: 6,
|
||||
text: type,
|
||||
),
|
||||
PBadge(right: 6, top: 6, text: type),
|
||||
],
|
||||
);
|
||||
},
|
||||
@@ -99,17 +96,17 @@ class SubItem extends StatelessWidget {
|
||||
);
|
||||
return Expanded(
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: .none,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: .start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
item.title!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.start,
|
||||
overflow: .ellipsis,
|
||||
textAlign: .start,
|
||||
style: const TextStyle(
|
||||
letterSpacing: 0.3,
|
||||
),
|
||||
@@ -117,31 +114,60 @@ class SubItem extends StatelessWidget {
|
||||
),
|
||||
Text(
|
||||
'UP主: ${item.upper!.name!}',
|
||||
textAlign: TextAlign.start,
|
||||
textAlign: .start,
|
||||
style: style,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'${item.mediaCount}个视频',
|
||||
textAlign: TextAlign.start,
|
||||
textAlign: .start,
|
||||
style: style,
|
||||
),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
height: 35,
|
||||
width: 35,
|
||||
child: IconButton(
|
||||
onPressed: cancelSub,
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: theme.colorScheme.outline,
|
||||
padding: EdgeInsets.zero,
|
||||
bottom: -8,
|
||||
width: 29,
|
||||
height: 29,
|
||||
child: PopupMenuButton(
|
||||
padding: .zero,
|
||||
tooltip: '功能菜单',
|
||||
icon: Icon(
|
||||
Icons.more_vert_outlined,
|
||||
color: theme.colorScheme.outline,
|
||||
size: 18,
|
||||
),
|
||||
icon: const Icon(Icons.delete_outline, size: 18),
|
||||
position: .under,
|
||||
itemBuilder: (_) => [
|
||||
PopupMenuItem(
|
||||
onTap: () => Get.toNamed('/member?mid=${item.upper?.mid}'),
|
||||
height: 38,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(MdiIcons.accountCircleOutline, size: 16),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'访问:${item.upper?.name}',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: cancelSub,
|
||||
height: 38,
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(Icons.close_outlined, size: 16),
|
||||
SizedBox(width: 6),
|
||||
Text('取消订阅', style: TextStyle(fontSize: 13)),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user