export settings file

Closes #950

tweak

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-08-07 20:59:58 +08:00
parent ef1ccabc8a
commit be998b8ee1
11 changed files with 80 additions and 39 deletions

View File

@@ -11,6 +11,7 @@ Widget videoProgressIndicator(double progress) => ClipRect(
child: LinearProgressIndicator(
minHeight: 10,
value: progress,
stopIndicatorColor: Colors.transparent,
),
),
);

View File

@@ -69,6 +69,10 @@ void main() async {
Request();
await Request.setCookie();
SmartDialog.config.toast = SmartConfigToast(
displayType: SmartToastType.onlyRefresh,
);
if (Pref.enableLog) {
// 异常捕获 logo记录
String buildConfig =

View File

@@ -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),

View File

@@ -143,7 +143,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
aspectRatioPresets: [
CropAspectRatioPreset.ratio16x9,
],
aspectRatioLockEnabled: true,
aspectRatioLockEnabled: false,
resetAspectRatioEnabled: false,
aspectRatioPickerButtonHidden: true,
),

View File

@@ -39,13 +39,12 @@ class LiveRoomController extends GetxController {
Rx<RoomInfoH5Data?> roomInfoH5 = Rx<RoomInfoH5Data?>(null);
Rx<int?> liveTime = Rx<int?>(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(),
);
}

View File

@@ -354,11 +354,11 @@ class _LiveRoomPageState extends State<LiveRoomPage>
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<LiveRoomPage>
);
},
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<LiveDanmaku> {
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,

View File

@@ -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,

View File

@@ -177,8 +177,9 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
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<VideoDetailPageV>
} 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<VideoDetailPageV>
void dispose() {
_listenerFS?.cancel();
videoDetailController.skipTimer?.cancel();
videoDetailController.skipTimer = null;
videoDetailController
..skipTimer?.cancel()
..skipTimer = null;
try {
Get.delete<HorizontalMemberPageController>(
@@ -409,9 +412,10 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
videoDetailController
..makeHeartBeat()
..showVP = plPlayerController!.showVP.value;
plPlayerController!.removeStatusLister(playerListener);
plPlayerController!.removePositionListener(positionListener);
plPlayerController!.pause();
plPlayerController!
..removeStatusLister(playerListener)
..removePositionListener(positionListener)
..pause();
}
isShowing = false;
super.didPushNext();

View File

@@ -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;

View File

@@ -58,10 +58,9 @@ class PlayOrPauseButtonState extends State<PlayOrPauseButton>
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();
}

View File

@@ -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;
}