diff --git a/lib/common/widgets/image_grid/image_grid_builder.dart b/lib/common/widgets/image_grid/image_grid_builder.dart index 6d749034a..b718becd8 100644 --- a/lib/common/widgets/image_grid/image_grid_builder.dart +++ b/lib/common/widgets/image_grid/image_grid_builder.dart @@ -250,8 +250,8 @@ class RenderImageGrid extends RenderBox super.dispose(); } - @override - bool get isRepaintBoundary => true; // gif repaint + // @override + // bool get isRepaintBoundary => true; // gif repaint } class ImageGridRenderObjectElement extends RenderObjectElement { diff --git a/lib/common/widgets/image_grid/image_grid_view.dart b/lib/common/widgets/image_grid/image_grid_view.dart index 6db266ef3..7434b9eaf 100644 --- a/lib/common/widgets/image_grid/image_grid_view.dart +++ b/lib/common/widgets/image_grid/image_grid_view.dart @@ -223,9 +223,9 @@ class ImageGridView extends StatelessWidget { width: width, height: height, decoration: BoxDecoration( - color: Theme.of( + color: ColorScheme.of( context, - ).colorScheme.onInverseSurface.withValues(alpha: 0.4), + ).onInverseSurface.withValues(alpha: 0.4), ), child: Image.asset( Assets.loading, @@ -255,37 +255,17 @@ class ImageGridView extends StatelessWidget { getPlaceHolder: () => placeHolder, ), if (item.isLivePhoto) - const PBadge( - text: 'Live', - right: 8, - bottom: 8, - type: .gray, - ) + const PBadge(text: 'Live', right: 8, bottom: 8, type: .gray) else if (item.isLongPic) - const PBadge( - text: '长图', - right: 8, - bottom: 8, - ) + const PBadge(text: '长图', right: 8, bottom: 8) else if (item.isGif) - const PBadge( - text: 'GIF', - right: 8, - bottom: 8, - type: .gray, - ), + const PBadge(text: 'GIF', right: 8, bottom: 8, type: .gray), ], ); if (!item.isLongPic) { - child = Hero( - tag: '${item.url}$hashCode', - child: child, - ); + child = Hero(tag: '${item.url}$hashCode', child: child); } - return LayoutId( - id: index, - child: child, - ); + return LayoutId(id: index, child: child); }); }, ), diff --git a/lib/grpc/audio.dart b/lib/grpc/audio.dart index 76d8e0726..cc67a43cb 100644 --- a/lib/grpc/audio.dart +++ b/lib/grpc/audio.dart @@ -25,8 +25,8 @@ abstract final class AudioGrpc { playerArgs: PlayerArgs( qn: Int64(qn), fnval: Int64(fnval), - forceHost: Int64(2), - voiceBalance: Int64(1), + forceHost: Int64.TWO, + voiceBalance: Int64.ONE, ), ), PlayURLResp.fromBuffer, @@ -58,8 +58,8 @@ abstract final class AudioGrpc { playerArgs: PlayerArgs( qn: Int64(qn), fnval: Int64(fnval), - forceHost: Int64(2), - voiceBalance: Int64(1), + forceHost: Int64.TWO, + voiceBalance: Int64.ONE, ), extraId: extraId, sortOpt: SortOption(order: order), diff --git a/lib/main.dart b/lib/main.dart index d2ad010c0..f07434a4a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -170,14 +170,14 @@ void main() async { if (Pref.enableLog) { // 异常捕获 logo记录 + final apiVersion = NativePlayer.apiVersion; final customParameters = { 'Build Time': DateFormatUtils.format( BuildConfig.buildTime, format: DateFormatUtils.longFormatDs, ), 'Commit Hash': BuildConfig.commitHash, - 'MPV Api Version': - '${NativePlayer.apiVersion >> 16}.${NativePlayer.apiVersion & 0xFFFF}', + 'MPV Api Version': '${apiVersion >> 16}.${apiVersion & 0xFFFF}', }; final fileHandler = await JsonFileHandler.init(); diff --git a/lib/pages/about/view.dart b/lib/pages/about/view.dart index 7dab10a89..3c250f6ab 100644 --- a/lib/pages/about/view.dart +++ b/lib/pages/about/view.dart @@ -183,11 +183,7 @@ Commit Hash: ${BuildConfig.commitHash}''', onTap: AndroidHelper.openLinkVerifySettings, leading: const Icon(MdiIcons.linkBoxOutline), title: const Text('打开受支持的链接'), - trailing: Icon( - Icons.arrow_forward, - size: 16, - color: outline, - ), + trailing: Icon(Icons.arrow_forward, size: 16, color: outline), ), ListTile( onTap: () => Get.toNamed('/logs'), diff --git a/lib/pages/audio/view.dart b/lib/pages/audio/view.dart index 69b211c1a..75ef20b02 100644 --- a/lib/pages/audio/view.dart +++ b/lib/pages/audio/view.dart @@ -672,7 +672,6 @@ class _AudioPageState extends State { FontAwesomeIcons.solidThumbsUp, ), selectStatus: _controller.hasLike.value, - semanticsLabel: '点赞', text: NumUtils.numFormat(audioItem.stat.like), onStartTriple: _controller.onStartTriple, onCancelTriple: _controller.onCancelTriple, @@ -685,10 +684,7 @@ class _AudioPageState extends State { selectIcon: const Icon(FontAwesomeIcons.b), onTap: _controller.actionCoinVideo, selectStatus: _controller.hasCoin, - semanticsLabel: '投币', - text: NumUtils.numFormat( - audioItem.stat.coin, - ), + text: NumUtils.numFormat(audioItem.stat.coin), ), ), Obx( @@ -704,19 +700,13 @@ class _AudioPageState extends State { isLongPress: true, ), selectStatus: _controller.hasFav.value, - semanticsLabel: '收藏', - text: NumUtils.numFormat( - audioItem.stat.favourite, - ), + text: NumUtils.numFormat(audioItem.stat.favourite), ), ), ActionItem( icon: const Icon(FontAwesomeIcons.comment), onTap: _controller.showReply, - semanticsLabel: '评论', - text: NumUtils.numFormat( - audioItem.stat.reply, - ), + text: NumUtils.numFormat(audioItem.stat.reply), ), ActionItem( icon: const Icon( @@ -724,10 +714,7 @@ class _AudioPageState extends State { ), onTap: () => _controller.actionShareVideo(context), selectStatus: false, - semanticsLabel: '分享', - text: NumUtils.numFormat( - audioItem.stat.share, - ), + text: NumUtils.numFormat(audioItem.stat.share), ), if (audioItem.associatedItem.hasOid() && audioItem.associatedItem.subId.isNotEmpty) @@ -741,7 +728,6 @@ class _AudioPageState extends State { ); }, selectStatus: false, - semanticsLabel: '看MV', text: '看MV', ), ], diff --git a/lib/pages/common/publish/common_rich_text_pub_page.dart b/lib/pages/common/publish/common_rich_text_pub_page.dart index 350479f1f..3303dee35 100644 --- a/lib/pages/common/publish/common_rich_text_pub_page.dart +++ b/lib/pages/common/publish/common_rich_text_pub_page.dart @@ -223,9 +223,10 @@ abstract class CommonRichTextPubPageState const Duration(milliseconds: 500), () async { try { - List pickedFiles = await imagePicker.pickMultiImage( + final pickedFiles = await imagePicker.pickMultiImage( limit: limit, imageQuality: 100, + requestFullMetadata: false, ); if (pickedFiles.isNotEmpty) { for (int i = 0; i < pickedFiles.length; i++) { diff --git a/lib/pages/dynamics_create_vote/view.dart b/lib/pages/dynamics_create_vote/view.dart index bbe805274..25a648481 100644 --- a/lib/pages/dynamics_create_vote/view.dart +++ b/lib/pages/dynamics_create_vote/view.dart @@ -429,9 +429,10 @@ class _CreateVotePageState extends State { const Duration(milliseconds: 500), () async { try { - XFile? pickedFile = await imagePicker.pickImage( + final pickedFile = await imagePicker.pickImage( imageQuality: 100, source: ImageSource.gallery, + requestFullMetadata: false, ); if (pickedFile != null) { final path = pickedFile.path; diff --git a/lib/pages/fav_create/view.dart b/lib/pages/fav_create/view.dart index 4e89f51af..b81ac9634 100644 --- a/lib/pages/fav_create/view.dart +++ b/lib/pages/fav_create/view.dart @@ -117,9 +117,10 @@ class _CreateFavPageState extends State { Future _pickImg(BuildContext context, ThemeData theme) async { try { - XFile? pickedFile = await _imagePicker.pickImage( + final pickedFile = await _imagePicker.pickImage( source: ImageSource.gallery, imageQuality: 100, + requestFullMetadata: false, ); if (pickedFile != null && mounted) { String imgPath = pickedFile.path; diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index 9bf9af212..ed8c60a24 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -74,15 +74,16 @@ class _LoginPageState extends State { TextButton.icon( onPressed: () async { SmartDialog.showLoading(msg: '正在生成截图'); - RenderRepaintBoundary boundary = - globalKey.currentContext!.findRenderObject()! + final boundary = + globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary; final image = await boundary.toImage(pixelRatio: 3); - ByteData? byteData = await image.toByteData(format: .png); - Uint8List pngBytes = byteData!.buffer.asUint8List(); + final byteData = await image.toByteData(format: .png); + final pngBytes = byteData!.buffer.asUint8List(); + image.dispose(); SmartDialog.dismiss(); - String picName = - "${Constants.appName}_loginQRCode_${ImageUtils.time}"; + final picName = + "${Constants.appName}_loginQRCode_${_loginPageCtr.codeInfo.value.data.authCode.hashCode.toUnsigned(32).toRadixString(16)}"; ImageUtils.saveByteImg(bytes: pngBytes, fileName: picName); }, icon: const Icon(Icons.save), diff --git a/lib/pages/member_profile/view.dart b/lib/pages/member_profile/view.dart index 3c5781658..4594e4aac 100644 --- a/lib/pages/member_profile/view.dart +++ b/lib/pages/member_profile/view.dart @@ -465,9 +465,10 @@ class _EditProfilePageState extends State { Future _pickImg(ThemeData theme) async { try { - XFile? pickedFile = await _imagePicker.pickImage( + final pickedFile = await _imagePicker.pickImage( source: .gallery, imageQuality: 100, + requestFullMetadata: false, ); if (pickedFile != null && mounted) { String? imagePath = pickedFile.path; diff --git a/lib/pages/setting/widgets/ordered_multi_select_dialog.dart b/lib/pages/setting/widgets/ordered_multi_select_dialog.dart index 6d8900c16..7f1452173 100644 --- a/lib/pages/setting/widgets/ordered_multi_select_dialog.dart +++ b/lib/pages/setting/widgets/ordered_multi_select_dialog.dart @@ -88,7 +88,7 @@ class _OrderedMultiSelectDialogState ), TextButton( onPressed: () { - assert(_tempValues.values.isSorted((a, b) => a.compareTo(b))); + assert(_tempValues.values.isSorted(Comparable.compare)); Get.back(result: _tempValues.keys.toList()); }, child: const Text('确定'), diff --git a/lib/pages/video/introduction/pgc/view.dart b/lib/pages/video/introduction/pgc/view.dart index 68fbdf3b9..f7e6134c8 100644 --- a/lib/pages/video/introduction/pgc/view.dart +++ b/lib/pages/video/introduction/pgc/view.dart @@ -397,7 +397,6 @@ class _PgcIntroPageState extends State { icon: const Icon(FontAwesomeIcons.thumbsUp), selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp), selectStatus: introController.hasLike.value, - semanticsLabel: '点赞', text: NumUtils.numFormat(item.stat!.like), onStartTriple: introController.onStartTriple, onCancelTriple: introController.onCancelTriple, @@ -410,7 +409,6 @@ class _PgcIntroPageState extends State { selectIcon: const Icon(FontAwesomeIcons.b), onTap: introController.actionCoinVideo, selectStatus: introController.hasCoin, - semanticsLabel: '投币', text: NumUtils.numFormat(item.stat!.coin), ), ), @@ -425,7 +423,6 @@ class _PgcIntroPageState extends State { isLongPress: true, ), selectStatus: introController.hasFav.value, - semanticsLabel: '收藏', text: NumUtils.numFormat(item.stat!.favorite), ), ), @@ -436,7 +433,6 @@ class _PgcIntroPageState extends State { onTap: () => introController.handleAction(introController.viewLater), selectStatus: introController.hasLater.value, - semanticsLabel: '再看', text: '再看', ), ), @@ -444,7 +440,6 @@ class _PgcIntroPageState extends State { icon: const Icon(FontAwesomeIcons.shareFromSquare), onTap: () => introController.actionShareVideo(context), selectStatus: false, - semanticsLabel: '转发', text: NumUtils.numFormat(item.stat!.share), ), ], diff --git a/lib/pages/video/introduction/ugc/view.dart b/lib/pages/video/introduction/ugc/view.dart index d17a01ad5..4c130e92b 100644 --- a/lib/pages/video/introduction/ugc/view.dart +++ b/lib/pages/video/introduction/ugc/view.dart @@ -517,7 +517,6 @@ class _UgcIntroPanelState extends State { icon: const Icon(FontAwesomeIcons.thumbsUp), selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp), selectStatus: introController.hasLike.value, - semanticsLabel: '点赞', text: !isLoading ? NumUtils.numFormat(videoDetail.stat!.like) : null, @@ -533,7 +532,6 @@ class _UgcIntroPanelState extends State { introController.actionDislikeVideo, ), selectStatus: introController.hasDislike.value, - semanticsLabel: '点踩', text: "点踩", ), ), @@ -544,7 +542,6 @@ class _UgcIntroPanelState extends State { selectIcon: const Icon(FontAwesomeIcons.b), onTap: introController.actionCoinVideo, selectStatus: introController.hasCoin, - semanticsLabel: '投币', text: !isLoading ? NumUtils.numFormat(videoDetail.stat!.coin) : null, @@ -561,7 +558,6 @@ class _UgcIntroPanelState extends State { isLongPress: true, ), selectStatus: introController.hasFav.value, - semanticsLabel: '收藏', text: !isLoading ? NumUtils.numFormat(videoDetail.stat!.favorite) : null, @@ -574,7 +570,6 @@ class _UgcIntroPanelState extends State { onTap: () => introController.handleAction(introController.viewLater), selectStatus: introController.hasLater.value, - semanticsLabel: '再看', text: '再看', ), ), @@ -582,7 +577,6 @@ class _UgcIntroPanelState extends State { icon: const Icon(FontAwesomeIcons.shareFromSquare), onTap: () => introController.actionShareVideo(context), selectStatus: false, - semanticsLabel: '分享', text: !isLoading ? NumUtils.numFormat(videoDetail.stat!.share!) : null, diff --git a/lib/pages/video/introduction/ugc/widgets/action_item.dart b/lib/pages/video/introduction/ugc/widgets/action_item.dart index 9f6f9b2c0..2a1ea45a1 100644 --- a/lib/pages/video/introduction/ugc/widgets/action_item.dart +++ b/lib/pages/video/introduction/ugc/widgets/action_item.dart @@ -12,7 +12,6 @@ class ActionItem extends StatelessWidget { this.onLongPress, this.text, this.selectStatus = false, - required this.semanticsLabel, this.expand = true, this.animation, this.onStartTriple, @@ -26,7 +25,6 @@ class ActionItem extends StatelessWidget { final VoidCallback? onLongPress; final String? text; final bool selectStatus; - final String semanticsLabel; final bool expand; final Animation? animation; final VoidCallback? onStartTriple; @@ -53,11 +51,8 @@ class ActionItem extends StatelessWidget { children: [ AnimatedBuilder( animation: animation!, - builder: (context, child) => Arc( - size: 28, - color: primary, - progress: -animation!.value, - ), + builder: (context, child) => + Arc(size: 28, color: primary, progress: -animation!.value), ), child, ], @@ -69,7 +64,7 @@ class ActionItem extends StatelessWidget { child = Material( type: .transparency, child: InkWell( - borderRadius: const BorderRadius.all(Radius.circular(6)), + borderRadius: const .all(.circular(6)), onTap: _isThumbsUp ? null : onTap, onLongPress: _isThumbsUp ? null : onLongPress, onSecondaryTap: PlatformUtils.isMobile || _isThumbsUp diff --git a/lib/pages/video/reply_reply/view.dart b/lib/pages/video/reply_reply/view.dart index 64fb1cfb8..1ed1bb315 100644 --- a/lib/pages/video/reply_reply/view.dart +++ b/lib/pages/video/reply_reply/view.dart @@ -203,17 +203,16 @@ class _VideoReplyReplyPanelState extends State } return _header(theme, firstFloor); }), - _sortWidget(theme), + _sortWidget(theme.colorScheme), ], - Obx(() => _buildBody(theme, _controller.loadingState.value)), + Obx( + () => _buildBody(theme.colorScheme, _controller.loadingState.value), + ), ], ), ); if (widget.isNested) { - return ExtendedVisibilityDetector( - uniqueKey: Key(_tag), - child: child, - ); + return ExtendedVisibilityDetector(uniqueKey: Key(_tag), child: child); } return child; } @@ -243,9 +242,9 @@ class _VideoReplyReplyPanelState extends State ); } - Widget _sortWidget(ThemeData theme) { + Widget _sortWidget(ColorScheme colorScheme) { return SliverPinnedHeader( - backgroundColor: theme.colorScheme.surface, + backgroundColor: colorScheme.surface, child: Padding( padding: const EdgeInsets.fromLTRB(12, 2.5, 6, 2.5), child: Row( @@ -265,18 +264,11 @@ class _VideoReplyReplyPanelState extends State TextButton.icon( style: Style.buttonStyle, onPressed: _controller.queryBySort, - icon: Icon( - Icons.sort, - size: 16, - color: theme.colorScheme.secondary, - ), + icon: Icon(Icons.sort, size: 16, color: colorScheme.secondary), label: Obx( () => Text( _controller.sortType.value.text!, - style: TextStyle( - fontSize: 13, - color: theme.colorScheme.secondary, - ), + style: TextStyle(fontSize: 13, color: colorScheme.secondary), ), ), ), @@ -287,7 +279,7 @@ class _VideoReplyReplyPanelState extends State } Widget _buildBody( - ThemeData theme, + ColorScheme colorScheme, LoadingState?> loadingState, ) { final jumpIndex = _controller.index.value; @@ -305,15 +297,13 @@ class _VideoReplyReplyPanelState extends State return Container( height: 125, alignment: Alignment.center, - margin: EdgeInsets.only( - bottom: MediaQuery.viewPaddingOf(context).bottom, - ), + margin: .only(bottom: MediaQuery.viewPaddingOf(context).bottom), child: Text( _controller.isEnd ? '没有更多了' : '加载中...', textAlign: TextAlign.center, style: TextStyle( fontSize: 12, - color: theme.colorScheme.outline, + color: colorScheme.outline, ), ), ); @@ -323,13 +313,10 @@ class _VideoReplyReplyPanelState extends State return ColoredBoxTransition( color: _colorAnimation ??= _controller.animController.drive( ColorTween( - begin: theme.colorScheme.onInverseSurface, - end: theme.colorScheme.surface, - ).chain( - CurveTween( - curve: const Interval(0.8, 1.0), // 前0.8s不变, 后0.2s开始动画 - ), - ), + begin: colorScheme.onInverseSurface, + end: colorScheme.surface, + // 前0.8s不变, 后0.2s开始动画 + ).chain(CurveTween(curve: const Interval(0.8, 1.0))), ), child: child, ); diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index 7a15f3a4d..1f135f5aa 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -1404,9 +1404,7 @@ class _VideoDetailPageVState extends State return FilledButton.tonal( style: FilledButton.styleFrom( shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(6), - ), + borderRadius: .all(.circular(6)), ), backgroundColor: themeData .colorScheme @@ -1424,9 +1422,7 @@ class _VideoDetailPageVState extends State item, isStein: true, ); - videoDetailController.getSteinEdgeInfo( - item.id, - ); + videoDetailController.getSteinEdgeInfo(item.id); }, child: Text(item.option!), ); diff --git a/lib/pages/video/widgets/header_control.dart b/lib/pages/video/widgets/header_control.dart index 3c38ecf9b..1e121d08a 100644 --- a/lib/pages/video/widgets/header_control.dart +++ b/lib/pages/video/widgets/header_control.dart @@ -1776,11 +1776,8 @@ class HeaderControlState extends State FontAwesomeIcons.thumbsUp, color: Colors.white, ), - selectIcon: const Icon( - FontAwesomeIcons.solidThumbsUp, - ), + selectIcon: const Icon(FontAwesomeIcons.solidThumbsUp), selectStatus: introController.hasLike.value, - semanticsLabel: '点赞', animation: introController.tripleAnimation, onStartTriple: () { plPlayerController.tripling = true; @@ -1795,26 +1792,6 @@ class HeaderControlState extends State ), ), ), - if (introController case final UgcIntroController ugc) - SizedBox( - width: btnWidth, - height: btnHeight, - child: Obx( - () => ActionItem( - expand: false, - icon: const Icon( - FontAwesomeIcons.thumbsDown, - color: Colors.white, - ), - selectIcon: const Icon( - FontAwesomeIcons.solidThumbsDown, - ), - onTap: () => ugc.handleAction(ugc.actionDislikeVideo), - selectStatus: ugc.hasDislike.value, - semanticsLabel: '点踩', - ), - ), - ), SizedBox( width: btnWidth, height: btnHeight, @@ -1829,7 +1806,6 @@ class HeaderControlState extends State selectIcon: const Icon(FontAwesomeIcons.b), onTap: introController.actionCoinVideo, selectStatus: introController.hasCoin, - semanticsLabel: '投币', ), ), ), @@ -1851,7 +1827,6 @@ class HeaderControlState extends State isLongPress: true, ), selectStatus: introController.hasFav.value, - semanticsLabel: '收藏', ), ), ), @@ -1865,7 +1840,6 @@ class HeaderControlState extends State color: Colors.white, ), onTap: () => introController.actionShareVideo(context), - semanticsLabel: '分享', ), ), ], diff --git a/lib/pages/whisper_detail/view.dart b/lib/pages/whisper_detail/view.dart index fd69208ba..e82e7de69 100644 --- a/lib/pages/whisper_detail/view.dart +++ b/lib/pages/whisper_detail/view.dart @@ -336,9 +336,10 @@ class _WhisperDetailPageState ); } else { try { - final XFile? pickedFile = await imagePicker.pickImage( + final pickedFile = await imagePicker.pickImage( source: ImageSource.gallery, imageQuality: 100, + requestFullMetadata: false, ); if (pickedFile != null) { final path = pickedFile.path; diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 3945b9179..95545bd9c 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -27,6 +27,7 @@ import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart'; import 'package:PiliPlus/services/service_locator.dart'; import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/android/bindings.g.dart'; +import 'package:PiliPlus/utils/duration_utils.dart'; import 'package:PiliPlus/utils/extension/box_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/image_utils.dart'; @@ -35,7 +36,6 @@ import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; -import 'package:PiliPlus/utils/theme_utils.dart'; import 'package:archive/archive.dart' show getCrc32; import 'package:canvas_danmaku/canvas_danmaku.dart'; import 'package:flutter/foundation.dart' show kDebugMode; @@ -584,16 +584,12 @@ class PlPlayerController with BlockConfigMixin { assert(_videoPlayerController == null); final opt = { 'video-sync': Pref.videoSync, + if (Platform.isAndroid) 'ao': Pref.audioOutput, + 'volume': + (PlatformUtils.isMobile ? Pref.playerVolume : volume.value * 100) + .toString(), + 'volume-max': kMaxVolume.toString(), }; - if (Platform.isAndroid) { - opt['ao'] = Pref.audioOutput; - } - if (PlatformUtils.isMobile) { - opt['volume'] = Pref.playerVolume.toString(); - } else { - opt['volume'] = (volume.value * 100).toString(); - } - opt['volume-max'] = kMaxVolume.toString(); final player = await Player.create( configuration: PlayerConfiguration( @@ -1388,6 +1384,9 @@ class PlPlayerController with BlockConfigMixin { Future takeScreenshot() async { SmartDialog.showToast('截图中'); + final time = DurationUtils.formatDuration( + position.inMilliseconds / 1000, + ).replaceAll(':', '-'); final image = await videoPlayerController?.screenshot(); if (image != null) { SmartDialog.showToast('点击弹窗保存截图'); @@ -1400,7 +1399,7 @@ class PlPlayerController with BlockConfigMixin { if (bytes != null) { ImageUtils.saveByteImg( bytes: bytes.buffer.asUint8List(), - fileName: 'screenshot_${ImageUtils.time}', + fileName: 'screenshot_${cid}_$time', ); } }, @@ -1416,7 +1415,7 @@ class PlPlayerController with BlockConfigMixin { decoration: BoxDecoration( border: .all( width: 5, - color: ThemeUtils.theme.colorScheme.surface, + color: ColorScheme.of(context).surface, ), ), child: Padding( diff --git a/lib/plugin/pl_player/view/view.dart b/lib/plugin/pl_player/view/view.dart index d6c9b8a47..60beb9223 100644 --- a/lib/plugin/pl_player/view/view.dart +++ b/lib/plugin/pl_player/view/view.dart @@ -19,8 +19,6 @@ import 'package:PiliPlus/common/widgets/view_safe_area.dart'; import 'package:PiliPlus/models/common/video/video_quality.dart'; import 'package:PiliPlus/models/video/play/url.dart'; import 'package:PiliPlus/models_new/video/video_detail/episode.dart' as ugc; -import 'package:PiliPlus/models_new/video/video_detail/episode.dart'; -import 'package:PiliPlus/models_new/video/video_detail/section.dart'; import 'package:PiliPlus/models_new/video/video_detail/ugc_season.dart'; import 'package:PiliPlus/pages/common/common_intro_controller.dart'; import 'package:PiliPlus/pages/video/controller.dart'; @@ -452,9 +450,9 @@ class _PLVideoPlayerState extends State String bvid = plPlayerController.bvid; List episodes = []; if (isSeason) { - final List sections = videoDetail.ugcSeason!.sections!; + final sections = videoDetail.ugcSeason!.sections!; for (int i = 0; i < sections.length; i++) { - final List episodesList = sections[i].episodes!; + final episodesList = sections[i].episodes!; for (final item in episodesList) { if (item.cid == currentCid) { index = i; @@ -681,18 +679,12 @@ class _PLVideoPlayerState extends State if (videoInfo.dash == null) { return const SizedBox.shrink(); } - final List videoFormat = videoInfo.supportFormats!; - final int totalQaSam = videoFormat.length; - int usefulQaSam = 0; - final List video = videoInfo.dash!.video!; - final Set idSet = {}; - for (final VideoItem item in video) { - final int id = item.id!; - if (!idSet.contains(id)) { - idSet.add(id); - usefulQaSam++; - } - } + final videoFormat = videoInfo.supportFormats!; + final totalQaSam = videoFormat.length; + final usefulQaSam = videoInfo.dash!.video! + .map((i) => i.id) + .toSet() + .length; return PopupMenuButton( tooltip: '画质', requestFocus: false, @@ -760,16 +752,8 @@ class _PLVideoPlayerState extends State height: 30, tooltip: isFullScreen ? '退出全屏' : '全屏', icon: isFullScreen - ? const Icon( - Icons.fullscreen_exit, - size: 24, - color: Colors.white, - ) - : const Icon( - Icons.fullscreen, - size: 24, - color: Colors.white, - ), + ? const Icon(Icons.fullscreen_exit, size: 24, color: Colors.white) + : const Icon(Icons.fullscreen, size: 24, color: Colors.white), onTap: () => plPlayerController.triggerFullScreen(status: !isFullScreen), onSecondaryTap: () => plPlayerController.triggerFullScreen( diff --git a/lib/services/shutdown_timer_service.dart b/lib/services/shutdown_timer_service.dart index 9204dcf08..b8da27452 100644 --- a/lib/services/shutdown_timer_service.dart +++ b/lib/services/shutdown_timer_service.dart @@ -166,7 +166,7 @@ class ShutdownTimerService { const Center(child: Text('定时关闭', style: titleStyle)), const SizedBox(height: 10), ...{...scheduleTimeMinutes, _durationInMinutes} - .sorted((a, b) => a.compareTo(b)) + .sorted(Comparable.compare) .map( (minutes) => ListTile( dense: true, diff --git a/lib/utils/image_utils.dart b/lib/utils/image_utils.dart index 6494a0618..7d7677b48 100644 --- a/lib/utils/image_utils.dart +++ b/lib/utils/image_utils.dart @@ -19,14 +19,11 @@ import 'package:dio/dio.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; -import 'package:intl/intl.dart' show DateFormat; import 'package:live_photo_maker/live_photo_maker.dart'; import 'package:saver_gallery/saver_gallery.dart'; import 'package:share_plus/share_plus.dart'; abstract final class ImageUtils { - static String get time => - DateFormat('yyyy-MM-dd_HH-mm-ss').format(DateTime.now()); static final _albumPath = Platform.isAndroid ? 'Pictures/${Constants.appName}' : Constants.appName;