opt: pm share

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-04-26 10:26:16 +08:00
parent b8d2ff7e9b
commit 0bdf620c2f
9 changed files with 210 additions and 134 deletions

View File

@@ -349,12 +349,27 @@ class BangumiIntroController
try { try {
EpisodeItem item = bangumiItem!.episodes! EpisodeItem item = bangumiItem!.episodes!
.firstWhere((item) => item.epId == epId); .firstWhere((item) => item.epId == epId);
PageUtils.pmShareVideo( final title = '${bangumiItem!.title!} ${item.showTitle}';
id: epId!, PageUtils.pmShare(
source: 16, content: {
cover: item.cover!, "id": epId!.toString(),
title: '${bangumiItem!.title!} ${item.showTitle}', "title": title,
url: item.shareUrl, "url": item.shareUrl,
"headline": title,
"source": 16,
"extra": {},
"thumb": item.cover,
"source_desc": switch (bangumiItem!.type) {
1 => '番剧',
2 => '电影',
3 => '纪录片',
4 => '国创',
5 => '电视剧',
6 => '漫画',
7 => '综艺',
_ => null,
}
},
); );
} catch (e) { } catch (e) {
SmartDialog.showToast(e.toString()); SmartDialog.showToast(e.toString());

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/report.dart';
import 'package:PiliPlus/common/widgets/save_panel.dart'; import 'package:PiliPlus/common/widgets/save_panel.dart';
import 'package:PiliPlus/http/video.dart'; import 'package:PiliPlus/http/video.dart';
import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/request_utils.dart';
import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
@@ -284,6 +285,16 @@ class AuthorPanel extends StatelessWidget {
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,
), ),
), ),
ListTile(
onTap: () {
Get.back();
SavePanel.toSavePanel(item: item);
},
minLeadingWidth: 0,
leading: const Icon(Icons.save_alt, size: 19),
title: Text('保存动态',
style: Theme.of(context).textTheme.titleSmall!),
),
ListTile( ListTile(
title: Text( title: Text(
'分享动态', '分享动态',
@@ -297,16 +308,52 @@ class AuthorPanel extends StatelessWidget {
}, },
minLeadingWidth: 0, minLeadingWidth: 0,
), ),
ListTile( if (item.basic['comment_type'] == 17 ||
onTap: () { item.basic['comment_type'] == 11)
Get.back(); ListTile(
SavePanel.toSavePanel(item: item); title: Text(
}, '分享至消息',
minLeadingWidth: 0, style: Theme.of(context).textTheme.titleSmall,
leading: const Icon(Icons.save_alt, size: 19), ),
title: Text('保存动态', leading: const Icon(Icons.forward_to_inbox, size: 19),
style: Theme.of(context).textTheme.titleSmall!), onTap: () {
), Get.back();
try {
bool isDyn = item.basic['comment_type'] == 17;
String id = isDyn ? item.idStr : item.basic['rid_str'];
int source = isDyn ? 11 : 2;
String title;
if (item.modules.moduleDynamic.desc != null) {
title = item.modules.moduleDynamic.desc.text;
} else if (item.modules.moduleDynamic.major != null) {
title =
item.modules.moduleDynamic.major.opus.summary.text;
} else {
throw UnsupportedError(
'error getting title: {"type": ${item.basic['comment_type']}, "id": $id}');
}
String thumb = isDyn
? item.modules.moduleAuthor.face
: item
.modules.moduleDynamic.major.opus.pics.first.url;
PageUtils.pmShare(
content: {
"id": id,
"title": title,
"headline": "",
"source": source,
"extra": {},
"thumb": thumb,
"author": item.modules.moduleAuthor.name,
"author_id": item.modules.moduleAuthor.mid.toString()
},
);
} catch (e) {
SmartDialog.showToast(e.toString());
}
},
minLeadingWidth: 0,
),
ListTile( ListTile(
title: Text( title: Text(
'临时屏蔽:${item.modules?.moduleAuthor?.name}', '临时屏蔽:${item.modules?.moduleAuthor?.name}',
@@ -317,9 +364,9 @@ class AuthorPanel extends StatelessWidget {
Get.back(); Get.back();
Get.find<DynamicsController>() Get.find<DynamicsController>()
.tempBannedList .tempBannedList
.add(item.modules!.moduleAuthor!.mid!); .add(item.modules.moduleAuthor.mid);
SmartDialog.showToast( SmartDialog.showToast(
'已临时屏蔽${item.modules?.moduleAuthor?.name}(${item.modules!.moduleAuthor!.mid}),重启恢复'); '已临时屏蔽${item.modules?.moduleAuthor?.name}(${item.modules.moduleAuthor.mid}),重启恢复');
}, },
minLeadingWidth: 0, minLeadingWidth: 0,
), ),

View File

@@ -56,6 +56,7 @@ class HtmlRenderController extends ReplyController<MainListReply> {
'status': true, 'status': true,
'isFav': res['data']?['favorite'] ?? false, 'isFav': res['data']?['favorite'] ?? false,
'favNum': res['data']?['stats']?['favorite'] ?? 0, 'favNum': res['data']?['stats']?['favorite'] ?? 0,
'data': res['data'],
}); });
} }
}); });

View File

@@ -17,6 +17,7 @@ import 'package:PiliPlus/utils/utils.dart';
import 'package:easy_debounce/easy_throttle.dart'; import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:PiliPlus/common/skeleton/video_reply.dart'; import 'package:PiliPlus/common/skeleton/video_reply.dart';
@@ -633,6 +634,40 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
], ],
), ),
), ),
if (_htmlRenderCtr.dynamicType == 'read' &&
_htmlRenderCtr.favStat['status'])
PopupMenuItem(
onTap: () {
try {
PageUtils.pmShare(
content: {
"id": _htmlRenderCtr.id.substring(2),
"title": "- 哔哩哔哩专栏",
"headline": _htmlRenderCtr.favStat['data']['title'],
"source": 6,
"thumb": (_htmlRenderCtr.favStat['data']
['origin_image_urls'] as List?)
?.firstOrNull ??
'',
"author": _htmlRenderCtr.favStat['data']
['author_name'],
"author_id":
_htmlRenderCtr.favStat['data']['mid'].toString(),
},
);
} catch (e) {
SmartDialog.showToast(e.toString());
}
},
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.forward_to_inbox, size: 19),
SizedBox(width: 10),
Text('分享至动态'),
],
),
),
], ],
), ),
const SizedBox(width: 6) const SizedBox(width: 6)

View File

@@ -18,7 +18,6 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:PiliPlus/common/widgets/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/network_img_layer.dart';
import 'package:PiliPlus/plugin/pl_player/index.dart'; import 'package:PiliPlus/plugin/pl_player/index.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:screen_brightness/screen_brightness.dart'; import 'package:screen_brightness/screen_brightness.dart';
import '../../utils/storage.dart'; import '../../utils/storage.dart';
@@ -416,35 +415,6 @@ class _LiveRoomPageState extends State<LiveRoomPage>
), ),
], ],
), ),
const Spacer(),
Obx(
() => IconButton(
onPressed: plPlayerController.setOnlyPlayAudio,
icon: Icon(
plPlayerController.onlyPlayAudio.value
? MdiIcons.musicCircle
: MdiIcons.musicCircleOutline,
color: Colors.white,
),
),
),
IconButton(
tooltip: '刷新',
onPressed: () {
_futureBuilderFuture =
_liveRoomController.queryLiveInfo();
},
icon: const Icon(Icons.refresh),
),
IconButton(
tooltip: '浏览器打开',
onPressed: () {
PageUtils.inAppWebview(
'https://live.bilibili.com/h5/${_liveRoomController.roomId}',
off: true,
);
},
icon: const Icon(Icons.open_in_browser)),
], ],
), ),
); );
@@ -453,6 +423,71 @@ class _LiveRoomPageState extends State<LiveRoomPage>
} }
}, },
), ),
actions: [
IconButton(
tooltip: '刷新',
onPressed: () {
_futureBuilderFuture = _liveRoomController.queryLiveInfo();
},
icon: const Icon(Icons.refresh),
),
PopupMenuButton(
icon: const Icon(Icons.more_vert, size: 19),
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
PopupMenuItem(
onTap: () {
PageUtils.inAppWebview(
'https://live.bilibili.com/h5/${_liveRoomController.roomId}',
off: true,
);
},
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.open_in_browser, size: 19),
SizedBox(width: 10),
Text('浏览器打开'),
],
),
),
PopupMenuItem(
onTap: () {
try {
PageUtils.pmShare(
content: {
"cover": _liveRoomController
.roomInfoH5.value.roomInfo!.cover!,
"sourceID": _liveRoomController.roomId.toString(),
"title": _liveRoomController
.roomInfoH5.value.roomInfo!.title!,
"url":
"https://live.bilibili.com/${_liveRoomController.roomId}",
"authorID": _liveRoomController
.roomInfoH5.value.roomInfo!.uid
.toString(),
"source": "直播",
"desc": _liveRoomController
.roomInfoH5.value.roomInfo!.title!,
"author": _liveRoomController
.roomInfoH5.value.anchorInfo!.baseInfo!.uname,
},
);
} catch (e) {
SmartDialog.showToast(e.toString());
}
},
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.forward_to_inbox, size: 19),
SizedBox(width: 10),
Text('分享至消息'),
],
),
),
],
),
],
); );
Widget get _buildBodyH { Widget get _buildBodyH {

View File

@@ -509,13 +509,16 @@ class VideoIntroController extends GetxController {
onTap: () { onTap: () {
Get.back(); Get.back();
try { try {
PageUtils.pmShareVideo( PageUtils.pmShare(
author: videoDetail.value.owner!.name!, content: {
id: videoDetail.value.aid!, "id": videoDetail.value.aid!.toString(),
source: 5, "title": videoDetail.value.title!,
cover: videoDetail.value.pic!, "headline": videoDetail.value.title!,
title: videoDetail.value.title!, "source": 5,
bvid: videoDetail.value.bvid!, "thumb": videoDetail.value.pic!,
"author": videoDetail.value.owner!.name!,
"author_id": videoDetail.value.owner!.mid!.toString(),
},
); );
} catch (e) { } catch (e) {
SmartDialog.showToast(e.toString()); SmartDialog.showToast(e.toString());

View File

@@ -34,37 +34,21 @@ class UserModel {
int get hashCode => mid.hashCode; int get hashCode => mid.hashCode;
} }
class ShareVideoPanel extends StatefulWidget { class SharePanel extends StatefulWidget {
const ShareVideoPanel({ const SharePanel({
super.key, super.key,
this.author, required this.content,
required this.id,
required this.source,
required this.cover,
required this.title,
this.bvid,
this.url,
this.authorId,
this.sourceDesc,
this.userList, this.userList,
}); });
final String? author; final Map content;
final int id;
final int source;
final String cover;
final String title;
final String? bvid;
final String? url;
final int? authorId;
final String? sourceDesc;
final List<UserModel>? userList; final List<UserModel>? userList;
@override @override
State<ShareVideoPanel> createState() => _ShareVideoPanelState(); State<SharePanel> createState() => _SharePanelState();
} }
class _ShareVideoPanelState extends State<ShareVideoPanel> { class _SharePanelState extends State<SharePanel> {
int _selectedIndex = -1; int _selectedIndex = -1;
final List<UserModel> _userList = <UserModel>[]; final List<UserModel> _userList = <UserModel>[];
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
@@ -245,17 +229,9 @@ class _ShareVideoPanelState extends State<ShareVideoPanel> {
SmartDialog.showToast('请选择分享的用户'); SmartDialog.showToast('请选择分享的用户');
return; return;
} }
RequestUtils.pmShareVideo( RequestUtils.pmShare(
receiverId: _userList[_selectedIndex].mid, receiverId: _userList[_selectedIndex].mid,
author: widget.author, content: widget.content,
id: widget.id,
source: widget.source,
cover: widget.cover,
title: widget.title,
bvid: widget.bvid,
url: widget.url,
authorId: widget.authorId,
sourceDesc: widget.sourceDesc,
message: _controller.text, message: _controller.text,
); );
}, },

View File

@@ -28,17 +28,9 @@ import 'package:get/get.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class PageUtils { class PageUtils {
static void pmShareVideo({ static void pmShare({required Map content}) async {
String? author, // debugPrint(content.toString());
required int id,
required int source,
required String cover,
required String title,
String? bvid,
String? url,
int? authorId,
String? sourceDesc,
}) async {
List<UserModel> userList = <UserModel>[]; List<UserModel> userList = <UserModel>[];
final shareListRes = await GrpcRepo.shareList(size: 3); final shareListRes = await GrpcRepo.shareList(size: 3);
@@ -64,16 +56,8 @@ class PageUtils {
showModalBottomSheet( showModalBottomSheet(
context: Get.context!, context: Get.context!,
builder: (context) => ShareVideoPanel( builder: (context) => SharePanel(
author: author, content: content,
id: id,
source: source,
cover: cover,
title: title,
bvid: bvid,
url: url,
authorId: authorId,
sourceDesc: sourceDesc,
userList: userList, userList: userList,
), ),
useSafeArea: true, useSafeArea: true,

View File

@@ -39,17 +39,9 @@ class RequestUtils {
// 16番剧id 为 epid // 16番剧id 为 epid
// 17番剧 // 17番剧
// https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/message/private_msg_content.md // https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/message/private_msg_content.md
static Future pmShareVideo({ static Future pmShare({
required int receiverId, required int receiverId,
String? author, required Map content,
required int id,
required int source,
required String cover,
required String title,
String? bvid,
String? url,
int? authorId,
String? sourceDesc,
String? message, String? message,
ValueChanged<bool>? callback, ValueChanged<bool>? callback,
}) async { }) async {
@@ -59,22 +51,10 @@ class RequestUtils {
final videoRes = await GrpcRepo.sendMsg( final videoRes = await GrpcRepo.sendMsg(
senderUid: ownerMid, senderUid: ownerMid,
receiverId: receiverId, receiverId: receiverId,
content: jsonEncode( content: jsonEncode(content),
{ msgType: content['source'] is String
if (author != null) "author": author, ? MsgType.EN_MSG_TYPE_COMMON_SHARE_CARD
"headline": title, : MsgType.EN_MSG_TYPE_SHARE_V2,
"id": id,
"source": source,
"thumb": cover,
"title": title,
if (bvid != null) "bvid": bvid,
// pgc
if (url != null) "url": url,
if (authorId != null) "author_id": authorId,
if (sourceDesc != null) "source_desc": sourceDesc,
},
),
msgType: MsgType.EN_MSG_TYPE_SHARE_V2,
); );
if (videoRes['status']) { if (videoRes['status']) {