feat(interaction): 支持游客点赞收藏评论
This commit is contained in:
1 parent
188811fde6
commit
a3d50eb935
18 files changed
+364
-121
No files matched your search
@@ -9,7 +9,6 @@ import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../core/data/models/comment.dart';
|
||||
import '../../../core/data/services/auth_controller.dart';
|
||||
import '../../../core/data/services/comment_controller.dart';
|
||||
import '../../../core/platform/haptics.dart';
|
||||
import '../../../core/platform/keyboard_inset.dart';
|
||||
@@ -196,23 +195,20 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
||||
return;
|
||||
}
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
if (result.errorCode == 200007) {
|
||||
await ensureSignedIn(context);
|
||||
return;
|
||||
}
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(result.errorMessage ?? l10n.commentPostFailed)),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _authenticate() async {
|
||||
await ensureSignedIn(context);
|
||||
if (!mounted || !context.read<AuthController>().isSignedIn) return;
|
||||
_inputFocus.requestFocus();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final signedIn = context.watch<AuthController>().isSignedIn;
|
||||
final hasContent = _input.text.trim().isNotEmpty;
|
||||
final canPost = signedIn && hasContent && !widget.controller.submitting;
|
||||
final canPost = hasContent && !widget.controller.submitting;
|
||||
final multiline = _input.text.contains('\n');
|
||||
final bottomInset = _isAndroid
|
||||
? _pinnedKeyboardInset
|
||||
@@ -247,8 +243,8 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
||||
key: const Key('comment-composer-input'),
|
||||
controller: _input,
|
||||
focusNode: _inputFocus,
|
||||
readOnly: !signedIn,
|
||||
canRequestFocus: signedIn,
|
||||
readOnly: false,
|
||||
canRequestFocus: true,
|
||||
minLines: 1,
|
||||
maxLines: 4,
|
||||
maxLength: _maxCommentLength,
|
||||
@@ -262,9 +258,7 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
||||
),
|
||||
cursorColor: AppColors.blue,
|
||||
decoration: InputDecoration(
|
||||
hintText: signedIn
|
||||
? l10n.writeComment
|
||||
: l10n.commentLoginHint,
|
||||
hintText: l10n.writeComment,
|
||||
hintStyle: const TextStyle(
|
||||
color: AppColors.muted,
|
||||
fontSize: 14,
|
||||
@@ -278,7 +272,7 @@ class _CommentComposerSheetState extends State<CommentComposerSheet> {
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
),
|
||||
onTap: signedIn ? null : _authenticate,
|
||||
onTap: null,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
@@ -11,11 +11,9 @@ import '../../../core/data/models/comment.dart';
|
||||
import '../../../core/data/models/drama.dart';
|
||||
import '../../../core/data/repositories/comment_repository.dart';
|
||||
import '../../../core/data/repositories/interaction_repository.dart';
|
||||
import '../../../core/data/services/auth_controller.dart';
|
||||
import '../../../core/data/services/comment_controller.dart';
|
||||
import '../../../core/formatting/error_text.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/widgets/auth_gate.dart';
|
||||
import '../../../core/widgets/empty_state.dart';
|
||||
import '../../../l10n/app_localizations.dart';
|
||||
import 'comment_composer_sheet.dart';
|
||||
@@ -29,7 +27,7 @@ const double _sheetRadius = 20;
|
||||
const double _headerHeight = 44;
|
||||
const double _composerTopGap = 8;
|
||||
|
||||
/// 服务端评论底部弹窗:匿名列表、游标翻页、回复与登录发布。
|
||||
/// 服务端评论底部弹窗:匿名列表、游标翻页、回复与设备身份发布。
|
||||
class DramaCommentsSheet extends StatefulWidget {
|
||||
const DramaCommentsSheet({super.key, required this.drama, this.episodeId});
|
||||
|
||||
@@ -92,8 +90,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
}
|
||||
|
||||
Future<void> _openComposer({DramaComment? replyTo}) async {
|
||||
await ensureSignedIn(context);
|
||||
if (!mounted || !context.read<AuthController>().isSignedIn) return;
|
||||
if (!mounted) return;
|
||||
_removeComposerOverlay();
|
||||
final entry = OverlayEntry(
|
||||
builder: (_) => CommentComposerSheet(
|
||||
@@ -222,7 +219,6 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
Widget _content(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final count = _serverCount ?? _controller.exactCount;
|
||||
final signedIn = context.watch<AuthController>().isSignedIn;
|
||||
final composerReserve = _composerHeight + _composerTopGap;
|
||||
return Column(
|
||||
key: const Key('comment-sheet-content'),
|
||||
@@ -269,7 +265,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
Padding(
|
||||
key: const Key('comment-composer-area'),
|
||||
padding: const EdgeInsets.only(top: _composerTopGap),
|
||||
child: _fakeComposer(l10n, signedIn: signedIn),
|
||||
child: _fakeComposer(l10n),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -352,7 +348,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
return const SizedBox(height: 8);
|
||||
}
|
||||
|
||||
Widget _fakeComposer(AppLocalizations l10n, {required bool signedIn}) {
|
||||
Widget _fakeComposer(AppLocalizations l10n) {
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: _openComposer,
|
||||
@@ -372,7 +368,7 @@ class _DramaCommentsSheetState extends State<DramaCommentsSheet> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16),
|
||||
child: Text(
|
||||
signedIn ? l10n.writeComment : l10n.commentLoginHint,
|
||||
l10n.writeComment,
|
||||
key: const Key('comment-input-placeholder-label'),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@@ -49,7 +49,8 @@ class PlayerBlockedNotice extends StatelessWidget {
|
||||
|
||||
bool get _needsUnlock =>
|
||||
accessType == PlayTicket.coinRequired ||
|
||||
accessType == PlayTicket.vipRequired;
|
||||
accessType == PlayTicket.vipRequired ||
|
||||
(accessType == null && episode.locked);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
Reference in new issue
Block a user