Compare commits

...

9 Commits

Author SHA1 Message Date
18960c1d02 v1.0.23 更新日志 2024-05-05 18:13:39 +08:00
f1bb21981a Update beta_ci.yml 2024-05-03 14:52:47 +08:00
f598c81b53 v1.0.22 更新日志 2024-04-30 23:07:36 +08:00
ec7762644b mod: findClosestNumber 2024-04-05 00:02:31 +08:00
5500a58c32 mod: 优化selectDialog选择逻辑 2024-04-05 00:02:31 +08:00
2ba72e3792 Update README.md 2024-04-03 23:59:24 +08:00
25c416f9bf Merge branch 'fix' 2024-04-03 23:20:44 +08:00
9ec9fc2830 Merge branch 'feature-updateVideoDetailStructure' 2024-04-03 23:20:21 +08:00
c0f3b4f3a2 fix: 全屏时展示弹幕操作 2024-04-02 23:13:15 +08:00
9 changed files with 196 additions and 31 deletions

View File

@ -4,7 +4,7 @@ on:
workflow_dispatch:
push:
branches:
- "main"
- "x-main"
paths-ignore:
- "**.md"
- "**.txt"

View File

@ -26,13 +26,13 @@
Xcode 13.4 不支持**auto_orientation**,请注释相关代码
```bash
[] Flutter (Channel stable, 3.16.4, on macOS 14.1.2 23B92 darwin-arm64, locale
[] Flutter (Channel stable, 3.16.5, on macOS 14.1.2 23B92 darwin-arm64, locale
zh-Hans-CN)
[] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[] Xcode - develop for iOS and macOS (Xcode 15.1)
[] Chrome - develop for the web
[] Android Studio (version 2022.3)
[] VS Code (version 1.85.1)
[] VS Code (version 1.87.2)
[] Connected device (3 available)
[] Network resources
@ -44,6 +44,9 @@ Xcode 13.4 不支持**auto_orientation**,请注释相关代码
## 技术交流
Telegram: https://t.me/+lm_oOVmF0RJiODk1
Tg Beta版本@PiliPala_Beta
QQ频道: https://pd.qq.com/s/365esodk3

29
change_log/1.0.22.0430.md Normal file
View File

@ -0,0 +1,29 @@
## 1.0.22
明天晚上或者后天晚上应该会更新
### 功能
+ 字幕
+ 全屏时选集
+ 动态转发
+ 评论视频并转发
+ 收藏夹删除
+ 合集显示封面
+ 底部导航栏编辑、排序功能
+ 历史记录进度条展示
+ 直播画质切换
+ 排行榜功能
+ 视频详情页推荐视频开关
+ 显示联合投稿up
### 修复
+ 收藏夹个数错误
+ 封面保存权限问题
+ 合集最后1p未展示
+ up主页关注按钮触发灰屏
### 优化
+ 视频简介查看逻辑
更多更新日志可在Github上查看
问题反馈、功能建议请查看「关于」页面。

15
change_log/1.0.23.0505.md Normal file
View File

@ -0,0 +1,15 @@
## 1.0.23
### 功能
+ 封面下载
### 修复
+ 全屏问题
+ 视频播放器灰屏问题
+ 评论区点击区域问题
+ 动态详情跳转异常问题
更多更新日志可在Github上查看
问题反馈、功能建议请查看「关于」页面。

View File

@ -44,6 +44,7 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
setState(() {
_tempValue = value as T;
});
Navigator.pop(context, _tempValue);
},
),
]
@ -51,19 +52,6 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
),
);
}),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(
'取消',
style: TextStyle(color: Theme.of(context).colorScheme.outline),
),
),
TextButton(
onPressed: () => Navigator.pop(context, _tempValue),
child: const Text('确定'),
)
],
);
}
}

View File

@ -91,7 +91,7 @@ class VideoDetailController extends GetxController
late bool enableCDN;
late int? cacheVideoQa;
late String cacheDecode;
late int cacheAudioQa;
late int defaultAudioQa;
PersistentBottomSheetController? replyReplyBottomSheetCtr;
RxList<SubTitileContentModel> subtitleContents =
@ -146,7 +146,7 @@ class VideoDetailController extends GetxController
// 预设的解码格式
cacheDecode = setting.get(SettingBoxKey.defaultDecode,
defaultValue: VideoDecodeFormats.values.last.code);
cacheAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
defaultAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
defaultValue: AudioQuality.hiRes.code);
oid.value = IdUtils.bv2av(Get.parameters['bvid']!);
getSubtitle();
@ -353,9 +353,9 @@ class VideoDetailController extends GetxController
if (audiosList.isNotEmpty) {
final List<int> numbers = audiosList.map((map) => map.id!).toList();
int closestNumber = Utils.findClosestNumber(cacheAudioQa, numbers);
if (!numbers.contains(cacheAudioQa) &&
numbers.any((e) => e > cacheAudioQa)) {
int closestNumber = Utils.findClosestNumber(defaultAudioQa, numbers);
if (!numbers.contains(defaultAudioQa) &&
numbers.any((e) => e > defaultAudioQa)) {
closestNumber = 30280;
}
firstAudio = audiosList.firstWhere((e) => e.id == closestNumber);

View File

@ -17,6 +17,7 @@ import 'package:pilipala/plugin/pl_player/index.dart';
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
import 'package:pilipala/utils/storage.dart';
import 'package:pilipala/services/shutdown_timer_service.dart';
import '../../../../http/danmaku.dart';
import '../../../../models/common/search_type.dart';
import '../../../../models/video_detail_res.dart';
import '../introduction/index.dart';
@ -52,7 +53,7 @@ class _HeaderControlState extends State<HeaderControl> {
final Box<dynamic> videoStorage = GStrorage.video;
late List<double> speedsList;
double buttonSpace = 8;
bool showTitle = false;
RxBool isFullScreen = false.obs;
late String heroTag;
late VideoIntroController videoIntroController;
late VideoDetailData videoDetail;
@ -69,13 +70,8 @@ class _HeaderControlState extends State<HeaderControl> {
}
void fullScreenStatusListener() {
widget.videoDetailCtr!.plPlayerController.isFullScreen
.listen((bool isFullScreen) {
if (isFullScreen) {
showTitle = true;
} else {
showTitle = false;
}
widget.videoDetailCtr!.plPlayerController.isFullScreen.listen((bool val) {
isFullScreen.value = val;
/// TODO setState() called after dispose()
if (mounted) {
@ -218,6 +214,87 @@ class _HeaderControlState extends State<HeaderControl> {
);
}
/// 发送弹幕
void showShootDanmakuSheet() {
final TextEditingController textController = TextEditingController();
bool isSending = false; // 追踪是否正在发送
showDialog(
context: Get.context!,
builder: (BuildContext context) {
// TODO: 支持更多类型和颜色的弹幕
return AlertDialog(
title: const Text('发送弹幕(测试)'),
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return TextField(
controller: textController,
);
}),
actions: [
TextButton(
onPressed: () => Get.back(),
child: Text(
'取消',
style: TextStyle(color: Theme.of(context).colorScheme.outline),
),
),
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return TextButton(
onPressed: isSending
? null
: () async {
final String msg = textController.text;
if (msg.isEmpty) {
SmartDialog.showToast('弹幕内容不能为空');
return;
} else if (msg.length > 100) {
SmartDialog.showToast('弹幕内容不能超过100个字符');
return;
}
setState(() {
isSending = true; // 开始发送,更新状态
});
//修改按钮文字
final dynamic res = await DanmakaHttp.shootDanmaku(
oid: widget.videoDetailCtr!.cid.value,
msg: textController.text,
bvid: widget.videoDetailCtr!.bvid,
progress:
widget.controller!.position.value.inMilliseconds,
type: 1,
);
setState(() {
isSending = false; // 发送结束,更新状态
});
if (res['status']) {
SmartDialog.showToast('发送成功');
// 发送成功,自动预览该弹幕,避免重新请求
// TODO: 暂停状态下预览弹幕仍会移动与计时可考虑添加到dmSegList或其他方式实现
widget.controller!.danmakuController!.addItems([
DanmakuItem(
msg,
color: Colors.white,
time: widget
.controller!.position.value.inMilliseconds,
type: DanmakuItemType.scroll,
isSend: true,
)
]);
Get.back();
} else {
SmartDialog.showToast('发送失败,错误信息为${res['msg']}');
}
},
child: Text(isSending ? '发送中...' : '发送'),
);
})
],
);
},
);
}
/// 定时关闭
void scheduleExit() async {
const List<int> scheduleTimeChoices = [
@ -1079,7 +1156,7 @@ class _HeaderControlState extends State<HeaderControl> {
},
),
SizedBox(width: buttonSpace),
if (showTitle &&
if (isFullScreen.value &&
isLandscape &&
widget.videoType == SearchType.video) ...[
Column(
@ -1131,6 +1208,43 @@ class _HeaderControlState extends State<HeaderControl> {
// ),
// fuc: () => _.screenshot(),
// ),
if (isFullScreen.value) ...[
SizedBox(
width: 56,
height: 34,
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () => showShootDanmakuSheet(),
child: const Text(
'发弹幕',
style: textStyle,
),
),
),
SizedBox(
width: 34,
height: 34,
child: Obx(
() => IconButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () {
_.isOpenDanmu.value = !_.isOpenDanmu.value;
},
icon: Icon(
_.isOpenDanmu.value
? Icons.subtitles_outlined
: Icons.subtitles_off_outlined,
size: 19,
color: Colors.white,
),
),
),
),
],
SizedBox(width: buttonSpace),
if (Platform.isAndroid) ...<Widget>[
SizedBox(

View File

@ -209,6 +209,8 @@ class Utils {
static int findClosestNumber(int target, List<int> numbers) {
int minDiff = 127;
int closestNumber = 0; // 初始化为0表示没有找到比目标值小的整数
// 向下查找
try {
for (int number in numbers) {
if (number < target) {
@ -221,6 +223,20 @@ class Utils {
}
}
} catch (_) {}
// 向上查找
if (closestNumber == 0) {
try {
for (int number in numbers) {
int diff = (number - target).abs();
if (diff < minDiff) {
minDiff = diff;
closestNumber = number;
}
}
} catch (_) {}
}
return closestNumber;
}

View File

@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.21+1021
version: 1.0.23+1023
environment:
sdk: ">=3.0.0 <4.0.0"