feat(player): 点赞与评论改为按集
This commit is contained in:
1 parent
e6f34977f5
commit
83822a0cbb
25 files changed
+337
-69
No files matched your search
@@ -230,7 +230,11 @@ class PlayerLogic extends ChangeNotifier {
|
||||
qualities = ticket.qualities;
|
||||
if (ticket.accessible && ticket.playUrl.isNotEmpty) {
|
||||
// 签名地址原样写回,不做任何拼接/改写(AppConfig.mediaUrl 只补 host)
|
||||
sessionEpisodes[index] = episode.withVideoUrl(ticket.playUrl);
|
||||
sessionEpisodes[index] = episode.withVideoUrl(
|
||||
ticket.playUrl,
|
||||
likeCount: ticket.likeCount,
|
||||
commentCount: ticket.commentCount,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
blockedTicket = ticket;
|
||||
@@ -797,7 +801,11 @@ class PlayerLogic extends ChangeNotifier {
|
||||
notify();
|
||||
}
|
||||
|
||||
Future<void> showComments(BuildContext context, Drama drama) async {
|
||||
Future<void> showComments(
|
||||
BuildContext context,
|
||||
Drama drama, {
|
||||
String? episodeId,
|
||||
}) async {
|
||||
session.setOverlayOpen(true);
|
||||
await session.playbackSettled;
|
||||
if (!context.mounted) {
|
||||
@@ -812,7 +820,7 @@ class PlayerLogic extends ChangeNotifier {
|
||||
showDragHandle: false,
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
builder: (_) => DramaCommentsSheet(drama: drama),
|
||||
builder: (_) => DramaCommentsSheet(drama: drama, episodeId: episodeId),
|
||||
);
|
||||
} finally {
|
||||
session.setOverlayOpen(false);
|
||||
|
||||
@@ -205,13 +205,22 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _openComments(BuildContext context, Drama drama) async {
|
||||
Future<void> _openComments(
|
||||
BuildContext context,
|
||||
Drama drama,
|
||||
Episode episode,
|
||||
) async {
|
||||
final comments = context.read<CommentRepository>();
|
||||
await openCommentsWithAuth(context, drama, show: logic.showComments);
|
||||
await openCommentsWithAuth(
|
||||
context,
|
||||
drama,
|
||||
show: (context, drama) =>
|
||||
logic.showComments(context, drama, episodeId: episode.id),
|
||||
);
|
||||
try {
|
||||
final count = await comments.count(drama.id);
|
||||
final count = await comments.count(drama.id, episodeId: episode.id);
|
||||
if (!mounted) return;
|
||||
setState(() => _commentCounts[drama.id] = count);
|
||||
setState(() => _commentCounts[episode.id] = count);
|
||||
} catch (_) {
|
||||
// 评论面板已经关闭,计数刷新失败时保留旧值即可。
|
||||
}
|
||||
@@ -456,18 +465,19 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
onBoostEnd: _endBoost,
|
||||
onTogglePlay: () =>
|
||||
logic.session.setUserWantsPlay(!logic.session.userWantsPlay),
|
||||
liked: interactions.isLiked(drama.id),
|
||||
likeCount: interactions.likeCount(drama.id) ?? drama.likeCount,
|
||||
liked: interactions.isEpisodeLiked(episode.id),
|
||||
likeCount:
|
||||
interactions.episodeLikeCount(episode.id) ?? episode.likeCount,
|
||||
favoriteCount: drama.favoriteCount == null
|
||||
? null
|
||||
: drama.favoriteCount! + (_favoriteDelta[drama.id] ?? 0),
|
||||
commentCount: _commentCounts[drama.id] ?? drama.commentCount,
|
||||
commentCount: _commentCounts[episode.id] ?? episode.commentCount,
|
||||
saved: context.watch<FavoriteController>().isSaved(drama.id),
|
||||
onLike: () async {
|
||||
if (await ensureSignedIn(context)) {
|
||||
if (!context.mounted) return;
|
||||
unawaited(context.read<Haptics>().lightImpact());
|
||||
final result = await interactions.toggleDramaLike(drama.id);
|
||||
final result = await interactions.toggleEpisodeLike(episode.id);
|
||||
if (!result.isSuccess && context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
@@ -481,7 +491,7 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
}
|
||||
},
|
||||
onSave: () => unawaited(_toggleSave(context, drama)),
|
||||
onComments: () => unawaited(_openComments(context, drama)),
|
||||
onComments: () => unawaited(_openComments(context, drama, episode)),
|
||||
onShare: () => logic.shareDrama(context, drama),
|
||||
onDetail: () => unawaited(logic.openDetail(context)),
|
||||
onOpenFullPlayer: () async {
|
||||
@@ -502,9 +512,11 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
drama: drama,
|
||||
episode: episode,
|
||||
controller: ready ? videoPort!.controller : null,
|
||||
liked: interactions.isLiked(drama.id),
|
||||
likeCount: interactions.likeCount(drama.id) ?? drama.likeCount,
|
||||
commentCount: _commentCounts[drama.id] ?? drama.commentCount,
|
||||
liked: interactions.isEpisodeLiked(episode.id),
|
||||
likeCount:
|
||||
interactions.episodeLikeCount(episode.id) ??
|
||||
episode.likeCount,
|
||||
commentCount: _commentCounts[episode.id] ?? episode.commentCount,
|
||||
favoriteCount: drama.favoriteCount == null
|
||||
? null
|
||||
: drama.favoriteCount! + (_favoriteDelta[drama.id] ?? 0),
|
||||
@@ -525,9 +537,10 @@ class _PlayerPageState extends State<PlayerPage>
|
||||
onDetail: () => unawaited(logic.openDetail(context)),
|
||||
onSpeed: () => unawaited(_openSpeedSheet(context)),
|
||||
onEpisodes: () => logic.showEpisodes(context),
|
||||
onComments: () => unawaited(_openComments(context, drama)),
|
||||
onComments: () =>
|
||||
unawaited(_openComments(context, drama, episode)),
|
||||
onLike: () =>
|
||||
unawaited(_toggleLike(context, interactions, drama)),
|
||||
unawaited(_toggleLike(context, interactions, episode)),
|
||||
onSave: () => unawaited(_toggleSave(context, drama)),
|
||||
onShare: () => logic.shareDrama(context, drama),
|
||||
onMore: () => _openMore(context, episode),
|
||||
|
||||
@@ -81,11 +81,11 @@ extension _PlayerViewActions on _PlayerPageState {
|
||||
Future<void> _toggleLike(
|
||||
BuildContext context,
|
||||
InteractionController interactions,
|
||||
Drama drama,
|
||||
Episode episode,
|
||||
) async {
|
||||
if (!await ensureSignedIn(context) || !context.mounted) return;
|
||||
unawaited(context.read<Haptics>().lightImpact());
|
||||
final result = await interactions.toggleDramaLike(drama.id);
|
||||
final result = await interactions.toggleEpisodeLike(episode.id);
|
||||
if (result.isSuccess || !context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
|
||||
@@ -31,9 +31,10 @@ const double _composerTopGap = 8;
|
||||
|
||||
/// 服务端评论底部弹窗:匿名列表、游标翻页、回复与登录发布。
|
||||
class DramaCommentsSheet extends StatefulWidget {
|
||||
const DramaCommentsSheet({super.key, required this.drama});
|
||||
const DramaCommentsSheet({super.key, required this.drama, this.episodeId});
|
||||
|
||||
final Drama drama;
|
||||
final String? episodeId;
|
||||
|
||||
@override
|
||||
State<DramaCommentsSheet> createState() => _DramaCommentsSheetState();
|
||||
@@ -56,6 +57,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
comments: _comments,
|
||||
interactions: context.read<InteractionRepository>(),
|
||||
dramaId: widget.drama.id,
|
||||
episodeId: widget.episodeId,
|
||||
);
|
||||
unawaited(_controller.load());
|
||||
unawaited(_refreshCount());
|
||||
@@ -77,7 +79,10 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
Future<void> _refreshCount() async {
|
||||
final request = ++_countRequest;
|
||||
try {
|
||||
final count = await _comments.count(widget.drama.id);
|
||||
final count = await _comments.count(
|
||||
widget.drama.id,
|
||||
episodeId: widget.episodeId,
|
||||
);
|
||||
if (!mounted || request != _countRequest) return;
|
||||
setState(() => _serverCount = count);
|
||||
} catch (_) {
|
||||
@@ -464,8 +469,9 @@ class _CommentThread extends StatelessWidget {
|
||||
Text(
|
||||
expanded
|
||||
? AppLocalizations.of(context)!.hideReplies
|
||||
: AppLocalizations.of(context)!
|
||||
.viewReplies(comment.replyCount),
|
||||
: AppLocalizations.of(
|
||||
context,
|
||||
)!.viewReplies(comment.replyCount),
|
||||
style: const TextStyle(
|
||||
color: AppColors.muted,
|
||||
fontSize: 12,
|
||||
|
||||
Reference in new issue
Block a user