diff --git a/lib/common/widgets/progress_bar/video_progress_indicator.dart b/lib/common/widgets/progress_bar/video_progress_indicator.dart index 9b7914443..29d840549 100644 --- a/lib/common/widgets/progress_bar/video_progress_indicator.dart +++ b/lib/common/widgets/progress_bar/video_progress_indicator.dart @@ -11,6 +11,7 @@ Widget videoProgressIndicator(double progress) => ClipRect( child: LinearProgressIndicator( minHeight: 10, value: progress, + stopIndicatorColor: Colors.transparent, ), ), ); diff --git a/lib/main.dart b/lib/main.dart index e8e983e9d..ac8950eb1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -69,6 +69,10 @@ void main() async { Request(); await Request.setCookie(); + SmartDialog.config.toast = SmartConfigToast( + displayType: SmartToastType.onlyRefresh, + ); + if (Pref.enableLog) { // 异常捕获 logo记录 String buildConfig = diff --git a/lib/pages/about/view.dart b/lib/pages/about/view.dart index 80c21f816..65159c90b 100644 --- a/lib/pages/about/view.dart +++ b/lib/pages/about/view.dart @@ -15,12 +15,16 @@ import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/update.dart'; import 'package:PiliPlus/utils/utils.dart'; +import 'package:dio/dio.dart' show Headers; +import 'package:document_file_save_plus/document_file_save_plus_platform_interface.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart' show Clipboard, ClipboardData; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; +import 'package:intl/intl.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'package:share_plus/share_plus.dart'; class AboutPage extends StatefulWidget { const AboutPage({super.key, this.showAppBar}); @@ -313,6 +317,42 @@ Commit Hash: ${BuildConfig.commitHash}''', clipBehavior: Clip.hardEdge, title: const Text('导入/导出设置'), children: [ + ListTile( + dense: true, + title: const Text('导出文件至本地', style: style), + onTap: () async { + Get.back(); + final res = utf8.encode(GStorage.exportAllSettings()); + final name = + 'piliplus_settings_${context.isTablet ? 'pad' : 'phone'}_' + '${DateFormat('yyyyMMddHHmmss').format(DateTime.now())}.json'; + try { + DocumentFileSavePlusPlatform.instance + .saveMultipleFiles( + dataList: [res], + fileNameList: [name], + mimeTypeList: [Headers.jsonContentType], + ); + if (Platform.isAndroid) { + SmartDialog.showToast('已保存'); + } + } catch (e) { + SharePlus.instance.share( + ShareParams( + files: [ + XFile.fromData( + res, + name: name, + mimeType: Headers.jsonContentType, + ), + ], + sharePositionOrigin: + await Utils.sharePositionOrigin, + ), + ); + } + }, + ), ListTile( dense: true, title: const Text('导出设置至剪贴板', style: style), diff --git a/lib/pages/fav_create/view.dart b/lib/pages/fav_create/view.dart index dfa169bff..34842b1fd 100644 --- a/lib/pages/fav_create/view.dart +++ b/lib/pages/fav_create/view.dart @@ -143,7 +143,7 @@ class _CreateFavPageState extends State { aspectRatioPresets: [ CropAspectRatioPreset.ratio16x9, ], - aspectRatioLockEnabled: true, + aspectRatioLockEnabled: false, resetAspectRatioEnabled: false, aspectRatioPickerButtonHidden: true, ), diff --git a/lib/pages/live_room/controller.dart b/lib/pages/live_room/controller.dart index 922685473..f05c7cb19 100644 --- a/lib/pages/live_room/controller.dart +++ b/lib/pages/live_room/controller.dart @@ -39,13 +39,12 @@ class LiveRoomController extends GetxController { Rx roomInfoH5 = Rx(null); Rx liveTime = Rx(null); - static const periodMins = 5; Timer? liveTimeTimer; void startLiveTimer() { if (liveTime.value != null) { liveTimeTimer ??= Timer.periodic( - const Duration(minutes: periodMins), + const Duration(minutes: 5), (_) => liveTime.refresh(), ); } diff --git a/lib/pages/live_room/view.dart b/lib/pages/live_room/view.dart index ae1d84b47..271854827 100644 --- a/lib/pages/live_room/view.dart +++ b/lib/pages/live_room/view.dart @@ -354,11 +354,11 @@ class _LiveRoomPageState extends State if (text.isNotEmpty) { text += ' '; } - text += - '开播${DurationUtil.formatDurationBetween( - liveTime * 1000, - DateTime.now().millisecondsSinceEpoch, - )}'; + final duration = DurationUtil.formatDurationBetween( + liveTime * 1000, + DateTime.now().millisecondsSinceEpoch, + ); + text += duration.isEmpty ? '刚刚开播' : '开播$duration'; } if (text.isEmpty) { return const SizedBox.shrink(); @@ -616,7 +616,7 @@ class _LiveRoomPageState extends State ); }, transitionDuration: fromEmote - ? const Duration(milliseconds: 300) + ? const Duration(milliseconds: 400) : const Duration(milliseconds: 500), transitionBuilder: (context, animation, secondaryAnimation, child) { var tween = Tween( @@ -689,12 +689,8 @@ class _LiveDanmakuState extends State { area: plPlayerController.showArea, opacity: plPlayerController.danmakuOpacity, hideTop: plPlayerController.blockTypes.contains(5), - hideScroll: plPlayerController.blockTypes.contains( - 2, - ), - hideBottom: plPlayerController.blockTypes.contains( - 4, - ), + hideScroll: plPlayerController.blockTypes.contains(2), + hideBottom: plPlayerController.blockTypes.contains(4), duration: plPlayerController.danmakuDuration / plPlayerController.playbackSpeed, diff --git a/lib/pages/live_room/widgets/bottom_control.dart b/lib/pages/live_room/widgets/bottom_control.dart index 07a6980a8..db207fa44 100644 --- a/lib/pages/live_room/widgets/bottom_control.dart +++ b/lib/pages/live_room/widgets/bottom_control.dart @@ -35,10 +35,7 @@ class BottomControl extends StatelessWidget { titleSpacing: 14, title: Row( children: [ - PlayOrPauseButton( - plPlayerController: plPlayerController, - ), - const SizedBox(width: 10), + PlayOrPauseButton(plPlayerController: plPlayerController), ComBtn( icon: const Icon( Icons.refresh, diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index 13c674cc2..e476e1114 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -177,8 +177,9 @@ class _VideoDetailPageVState extends State videoDetailController.queryVideoUrl(); if (videoDetailController.autoPlay.value) { plPlayerController = videoDetailController.plPlayerController; - plPlayerController!.addStatusLister(playerListener); - plPlayerController!.addPositionListener(positionListener); + plPlayerController! + ..addStatusLister(playerListener) + ..addPositionListener(positionListener); await plPlayerController!.autoEnterFullscreen(); } } @@ -327,8 +328,9 @@ class _VideoDetailPageVState extends State } else { await videoDetailController.playerInit(autoplay: true); } - plPlayerController!.addStatusLister(playerListener); - plPlayerController!.addPositionListener(positionListener); + plPlayerController! + ..addStatusLister(playerListener) + ..addPositionListener(positionListener); await plPlayerController!.autoEnterFullscreen(); } @@ -336,8 +338,9 @@ class _VideoDetailPageVState extends State void dispose() { _listenerFS?.cancel(); - videoDetailController.skipTimer?.cancel(); - videoDetailController.skipTimer = null; + videoDetailController + ..skipTimer?.cancel() + ..skipTimer = null; try { Get.delete( @@ -409,9 +412,10 @@ class _VideoDetailPageVState extends State videoDetailController ..makeHeartBeat() ..showVP = plPlayerController!.showVP.value; - plPlayerController!.removeStatusLister(playerListener); - plPlayerController!.removePositionListener(positionListener); - plPlayerController!.pause(); + plPlayerController! + ..removeStatusLister(playerListener) + ..removePositionListener(positionListener) + ..pause(); } isShowing = false; super.didPushNext(); diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index d63247786..b84e03e36 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -1451,6 +1451,9 @@ class PlPlayerController { dynamic pgcType, VideoType? videoType, }) async { + if (isLive) { + return; + } if (!enableHeart || MineController.anonymity.value || progress == 0) { return; } else if (playerStatus.status.value == PlayerStatus.paused) { @@ -1458,9 +1461,6 @@ class PlPlayerController { return; } } - if (isLive) { - return; - } bool isComplete = playerStatus.status.value == PlayerStatus.completed || type == HeartBeatType.completed; diff --git a/lib/plugin/pl_player/widgets/play_pause_btn.dart b/lib/plugin/pl_player/widgets/play_pause_btn.dart index ccc5105d6..01d0a6586 100644 --- a/lib/plugin/pl_player/widgets/play_pause_btn.dart +++ b/lib/plugin/pl_player/widgets/play_pause_btn.dart @@ -58,10 +58,9 @@ class PlayOrPauseButtonState extends State height: 34, child: GestureDetector( behavior: HitTestBehavior.opaque, - onTap: () async { + onTap: () { if (player.state.completed) { - await player.seek(Duration.zero); - player.play(); + player.seek(Duration.zero).whenComplete(player.play); } else { player.playOrPause(); } diff --git a/lib/utils/duration_util.dart b/lib/utils/duration_util.dart index db1ba1960..d68019af4 100644 --- a/lib/utils/duration_util.dart +++ b/lib/utils/duration_util.dart @@ -37,9 +37,11 @@ class DurationUtil { int diffMillis = endMillis - startMillis; final duration = Duration(milliseconds: diffMillis); - final years = duration.inDays ~/ 365; - final months = (duration.inDays % 365) ~/ 30; - final days = (duration.inDays % 365) % 30; + final inDays = duration.inDays; + final daysLeft = inDays % 365; + final years = inDays ~/ 365; + final months = daysLeft ~/ 30; + final days = daysLeft % 30; final hours = duration.inHours % 24; final minutes = duration.inMinutes % 60; @@ -49,8 +51,7 @@ class DurationUtil { if (months > 0) format += '$months月'; if (days > 0) format += '$days天'; if (hours > 0) format += '$hours小时'; - - format += '$minutes分钟'; + if (minutes > 0) format += '$minutes分钟'; return format; }