Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-05-18 12:02:54 +08:00
parent 344e2eb29c
commit 4acb4d4879
13 changed files with 25 additions and 280 deletions

View File

@@ -70,6 +70,8 @@ class PlDanmakuController {
final danmakuWeight = DanmakuOptions.danmakuWeight;
final shouldFilter = filters.count != 0;
for (final element in elems) {
if (element.mode == 7) continue;
if (_isLogin) {
element.isSelf = element.midHash == _plPlayerController.midHash;
}

View File

@@ -1,8 +1,5 @@
import 'dart:convert';
import 'package:PiliPlus/grpc/bilibili/community/service/dm/v1.pb.dart';
import 'package:PiliPlus/pages/danmaku/controller.dart';
import 'package:PiliPlus/pages/danmaku/danmaku_model.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
import 'package:PiliPlus/plugin/pl_player/utils/danmaku_options.dart';
@@ -40,7 +37,7 @@ class _PlDanmakuState extends State<PlDanmaku> {
PlPlayerController get playerController => widget.playerController;
late final PlDanmakuController _plDanmakuController;
DanmakuController<DanmakuExtra>? _controller;
DanmakuController? _controller;
int latestAddedPosition = -1;
@override
@@ -113,42 +110,17 @@ class _PlDanmakuState extends State<PlDanmaku> {
List<DanmakuElem>? currentDanmakuList = _plDanmakuController
.getCurrentDanmaku(currentPosition);
if (currentDanmakuList != null) {
final blockColorful = DanmakuOptions.blockColorful;
for (DanmakuElem e in currentDanmakuList) {
if (e.mode == 7) {
try {
_controller!.addDanmaku(
SpecialDanmakuContentItem.fromList(
DmUtils.decimalToColor(e.color),
e.fontsize.toDouble(),
jsonDecode(e.content.replaceAll('\n', '\\n')),
extra: VideoDanmaku(
id: e.id.toInt(),
mid: e.midHash,
like: e.likeCount.toInt(),
),
),
);
} catch (_) {}
} else {
_controller!.addDanmaku(
DanmakuContentItem(
e.content,
color: blockColorful
? Colors.white
: DmUtils.decimalToColor(e.color),
type: DmUtils.getPosition(e.mode),
isColorful: e.colorful == DmColorfulType.VipGradualColor,
count: e.count > 1 ? e.count : null,
selfSend: e.isSelf,
extra: VideoDanmaku(
id: e.id.toInt(),
mid: e.midHash,
like: e.likeCount.toInt(),
),
),
);
}
_controller!.addDanmaku(
DanmakuContentItem(
e.content,
color: DmUtils.decimalToColor(e.color),
type: DmUtils.getPosition(e.mode),
isColorful: e.colorful == DmColorfulType.VipGradualColor,
count: e.count > 1 ? e.count : null,
selfSend: e.isSelf,
),
);
}
}
}
@@ -175,7 +147,7 @@ class _PlDanmakuState extends State<PlDanmaku> {
? playerController.danmakuOpacity.value
: 0,
duration: const Duration(milliseconds: 100),
child: DanmakuScreen<DanmakuExtra>(
child: DanmakuScreen(
createdController: (e) {
playerController.danmakuController = _controller = e;
},

View File

@@ -22,7 +22,6 @@ import 'package:PiliPlus/pages/live_room/send_danmaku/view.dart';
import 'package:PiliPlus/pages/video/widgets/header_control.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/plugin/pl_player/models/data_source.dart';
import 'package:PiliPlus/plugin/pl_player/utils/danmaku_options.dart';
import 'package:PiliPlus/services/service_locator.dart';
import 'package:PiliPlus/tcp/live.dart';
import 'package:PiliPlus/utils/accounts.dart';
@@ -49,7 +48,7 @@ class LiveRoomController extends GetxController {
int roomId = Get.arguments;
int? ruid;
DanmakuController<DanmakuExtra>? danmakuController;
DanmakuController? danmakuController;
final plPlayerController = PlPlayerController.getInstance(isLive: true);
final isLoaded = false.obs;
@@ -407,7 +406,7 @@ class LiveRoomController extends GetxController {
..init();
}
void addDm(dynamic msg, [DanmakuContentItem<DanmakuExtra>? item]) {
void addDm(dynamic msg, [DanmakuContentItem? item]) {
if (plPlayerController.showDanmaku) {
if (item != null) {
danmakuController?.addDanmaku(item);
@@ -473,13 +472,10 @@ class LiveRoomController extends GetxController {
),
DanmakuContentItem(
msg,
color: DanmakuOptions.blockColorful
? Colors.white
: DmUtils.decimalToColor(extra['color']),
color: DmUtils.decimalToColor(extra['color']),
type: DmUtils.getPosition(extra['mode']),
// extra['send_from_me'] is invalid
selfSend: isLogin && uid == mid,
extra: liveExtra,
),
);
break;

View File

@@ -19,7 +19,6 @@ import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/common/live/live_contribution_rank_type.dart';
import 'package:PiliPlus/models_new/live/live_room_info_h5/data.dart';
import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
import 'package:PiliPlus/pages/danmaku/danmaku_model.dart';
import 'package:PiliPlus/pages/live_room/contribution_rank/controller.dart';
import 'package:PiliPlus/pages/live_room/contribution_rank/view.dart';
import 'package:PiliPlus/pages/live_room/controller.dart';
@@ -1044,7 +1043,7 @@ class _LiveDanmakuState extends State<LiveDanmaku> {
? plPlayerController.danmakuOpacity.value
: 0,
duration: const Duration(milliseconds: 100),
child: DanmakuScreen<DanmakuExtra>(
child: DanmakuScreen(
createdController: (e) {
widget.liveRoomController.danmakuController =
plPlayerController.danmakuController = e;

View File

@@ -1443,49 +1443,4 @@ class VideoDetailController extends GetxController
),
);
}
@pragma('vm:notify-debugger-on-exception')
Future<void> onCast() async {
SmartDialog.showLoading();
final res = await VideoHttp.tvPlayUrl(
cid: cid.value,
objectId: epId ?? aid,
playurlType: epId != null ? 2 : 1,
qn: currentVideoQa.value?.code,
);
SmartDialog.dismiss();
if (res case Success(:final response)) {
final first = response.durl?.firstOrNull;
if (first == null || first.playUrls.isEmpty) {
SmartDialog.showToast('不支持投屏');
return;
}
final url = VideoUtils.getCdnUrl(first.playUrls);
String? title;
try {
if (isUgc) {
title = Get.find<UgcIntroController>(
tag: heroTag,
).videoDetail.value.title;
} else {
title = Get.find<PgcIntroController>(
tag: heroTag,
).videoDetail.value.title;
}
} catch (_) {}
if (kDebugMode) {
debugPrint(title);
}
Get.toNamed(
'/dlna',
parameters: {
'url': url,
'title': ?title,
},
);
} else {
res.toast();
}
}
}

View File

@@ -6,9 +6,7 @@ import 'package:PiliPlus/http/danmaku.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/publish_panel_type.dart';
import 'package:PiliPlus/pages/common/publish/common_text_pub_page.dart';
import 'package:PiliPlus/pages/danmaku/danmaku_model.dart';
import 'package:PiliPlus/pages/setting/slide_color_picker.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:canvas_danmaku/models/danmaku_content_item.dart';
import 'package:flutter/material.dart';
@@ -22,7 +20,7 @@ class SendDanmakuPanel extends CommonTextPubPage {
final dynamic bvid;
final dynamic progress;
final ValueChanged<DanmakuContentItem<DanmakuExtra>> onSuccess;
final ValueChanged<DanmakuContentItem> onSuccess;
// config
final ({int? mode, int? fontSize, Color? color})? dmConfig;
@@ -460,17 +458,10 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
colorful: isColorful,
);
SmartDialog.dismiss();
if (res case Success(:final response)) {
if (res is Success) {
hasPub = true;
Get.back();
SmartDialog.showToast('发送成功');
VideoDanmaku? extra;
if (response.dmid case final dmid?) {
extra = VideoDanmaku(
id: dmid,
mid: PlPlayerController.instance!.midHash,
);
}
widget.onSuccess(
DanmakuContentItem(
editController.text,
@@ -482,7 +473,6 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
},
selfSend: true,
isColorful: isColorful,
extra: extra,
),
);
} else {

View File

@@ -4,7 +4,6 @@ import 'dart:io' show Platform, File;
import 'dart:typed_data' show Uint8List;
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/dialog/report.dart';
import 'package:PiliPlus/common/widgets/marquee.dart';
@@ -51,7 +50,6 @@ import 'package:PiliPlus/utils/storage_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:PiliPlus/utils/video_utils.dart';
import 'package:battery_plus/battery_plus.dart';
import 'package:canvas_danmaku/canvas_danmaku.dart';
import 'package:collection/collection.dart';
import 'package:dio/dio.dart';
import 'package:easy_debounce/easy_throttle.dart';
@@ -613,15 +611,6 @@ class HeaderControlState extends State<HeaderControl>
descPosType: .subtitle,
descFontSize: 12,
),
ListTile(
dense: true,
onTap: () {
Get.back();
showDanmakuPool();
},
leading: const Icon(CustomIcons.dm_on, size: 20),
title: const Text('弹幕列表', style: titleStyle),
),
ListTile(
dense: true,
onTap: () {
@@ -1496,142 +1485,6 @@ class HeaderControlState extends State<HeaderControl>
)?.whenComplete(plPlayerController.putSubtitleSettings);
}
void showDanmakuPool() {
final ctr = plPlayerController.danmakuController;
if (ctr == null) return;
showBottomSheet((context, setState) {
final theme = Theme.of(context);
return Container(
margin: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: theme.colorScheme.surface,
borderRadius: const BorderRadius.all(Radius.circular(12)),
),
child: Column(
children: [
Container(
height: 45,
padding: const EdgeInsets.symmetric(horizontal: 14),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: theme.colorScheme.outline.withValues(alpha: 0.1),
),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('弹幕列表'),
iconButton(
onPressed: () => setState(() {}),
icon: const Icon(Icons.refresh),
),
],
),
),
Expanded(
child: Material(
type: .transparency,
clipBehavior: .hardEdge,
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(12),
),
child: CustomScrollView(
slivers: [
?_buildDanmakuList(ctr.staticDanmaku.nonNulls.toList()),
?_buildDanmakuList(
ctr.scrollDanmaku.expand((e) => e).toList(),
),
?_buildDanmakuList(ctr.specialDanmaku.toList()),
const SliverToBoxAdapter(child: SizedBox(height: 12)),
],
),
),
),
],
),
);
});
}
Widget? _buildDanmakuList(List<DanmakuItem<DanmakuExtra>> list) {
if (list.isEmpty) return null;
return SliverList.builder(
itemCount: list.length,
itemBuilder: (context, index) {
final item = list[index];
final extra = item.content.extra! as VideoDanmaku;
return ListTile(
dense: true,
contentPadding: const EdgeInsets.symmetric(horizontal: 14),
onLongPress: () => Utils.copyText(item.content.text),
title: Text(
item.content.text,
style: const TextStyle(fontSize: 14),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
Builder(
builder: (context) => Stack(
clipBehavior: Clip.none,
children: [
iconButton(
onPressed: () async {
if (await HeaderControl.likeDanmaku(
extra,
plPlayerController.cid!,
) &&
context.mounted) {
(context as Element).markNeedsBuild();
}
},
icon: extra.isLike
? const Icon(CustomIcons.player_dm_tip_like_solid)
: const Icon(CustomIcons.player_dm_tip_like),
),
if (extra.like > 0)
Positioned(
left: 24.5,
top: 1.5,
child: Text(
extra.like.toString(),
style: const TextStyle(
fontSize: 10.5,
letterSpacing: 0,
// fontWeight: FontWeight.bold,
),
),
),
],
),
),
if (item.content.selfSend)
iconButton(
onPressed: () => HeaderControl.deleteDanmaku(
extra.id,
plPlayerController.cid!,
).then((_) => item.expired = true),
icon: const Icon(CustomIcons.player_dm_tip_recall),
)
else
iconButton(
onPressed: () => HeaderControl.reportDanmaku(
context,
extra: extra,
ctr: plPlayerController,
),
icon: const Icon(CustomIcons.player_dm_tip_back),
),
],
),
);
},
);
}
late final isFileSource = videoDetailCtr.isFileSource;
@override
@@ -1779,7 +1632,7 @@ class HeaderControlState extends State<HeaderControl>
);
}),
if (!isFileSource) ...[
if (!isFSOrPip) ...[
if (!isFSOrPip)
if (videoDetailCtr.isUgc)
SizedBox(
width: btnWidth,
@@ -1795,21 +1648,6 @@ class HeaderControlState extends State<HeaderControl>
),
),
),
SizedBox(
width: btnWidth,
height: btnHeight,
child: IconButton(
tooltip: '投屏',
style: btnStyle,
onPressed: videoDetailCtr.onCast,
icon: const Icon(
Icons.cast,
size: 19,
color: Colors.white,
),
),
),
],
if (plPlayerController.enableSponsorBlock)
SizedBox(
width: btnWidth,

View File

@@ -44,8 +44,6 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
(value: 2, label: '滚动'),
(value: 5, label: '顶部'),
(value: 4, label: '底部'),
(value: 6, label: '彩色'),
(value: 7, label: '高级'),
];
final danmakuController = plPlayerController.danmakuController;
@@ -140,7 +138,6 @@ mixin HeaderMixin<T extends StatefulWidget> on State<T> {
} else {
DanmakuOptions.blockTypes.add(blockType);
}
DanmakuOptions.blockColorful = DanmakuOptions.blockTypes.contains(6);
setState(() {});
setOptions();
}