diff --git a/lib/pages/fav_detail/widget/fav_video_card.dart b/lib/pages/fav_detail/widget/fav_video_card.dart index bbe84b018..9be59fa49 100644 --- a/lib/pages/fav_detail/widget/fav_video_card.dart +++ b/lib/pages/fav_detail/widget/fav_video_card.dart @@ -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)), + ], + ), + ), + ], ), ), ], diff --git a/lib/pages/history/view.dart b/lib/pages/history/view.dart index 2fbb77c50..dd9356fb4 100644 --- a/lib/pages/history/view.dart +++ b/lib/pages/history/view.dart @@ -68,10 +68,7 @@ class _HistoryPageState extends State 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 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 AppBar get _buildAppBar => AppBar( title: const Text('观看记录'), - bottom: _buildPauseTip, actions: [ IconButton( tooltip: '搜索', @@ -242,7 +236,7 @@ class _HistoryPageState extends State 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 TextSpan( children: [ WidgetSpan( - alignment: PlaceholderAlignment.middle, + alignment: .middle, child: Icon( Icons.info_outline, size: 18, @@ -268,13 +262,10 @@ class _HistoryPageState extends State ), ), 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), diff --git a/lib/pages/history/widgets/item.dart b/lib/pages/history/widgets/item.dart index 2c06d7f39..3ffceba3e 100644 --- a/lib/pages/history/widgets/item.dart +++ b/lib/pages/history/widgets/item.dart @@ -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, diff --git a/lib/pages/later/widgets/video_card_h_later.dart b/lib/pages/later/widgets/video_card_h_later.dart index 3ceb19cc7..309b7b700 100644 --- a/lib/pages/later/widgets/video_card_h_later.dart +++ b/lib/pages/later/widgets/video_card_h_later.dart @@ -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: [ + 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)), + ], + ), + ), + ], ), ), ], diff --git a/lib/pages/subscription/widgets/item.dart b/lib/pages/subscription/widgets/item.dart index bdf342fd5..45bcbf6b6 100644 --- a/lib/pages/subscription/widgets/item.dart +++ b/lib/pages/subscription/widgets/item.dart @@ -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)), + ], + ), + ), + ], ), ), ],