This commit is contained in:
Phuoc Nguyen
2025-11-11 16:02:09 +07:00
parent 2f296ad8d3
commit 0093b62c29
5 changed files with 117 additions and 139 deletions

View File

@@ -10,6 +10,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:share_plus/share_plus.dart';
import 'package:worker/core/constants/api_constants.dart';
import 'package:worker/core/constants/ui_constants.dart';
import 'package:worker/core/theme/colors.dart';
import 'package:worker/features/news/domain/entities/news_article.dart';
@@ -159,76 +161,73 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
// Article Body - Render HTML content
if (article.content != null && article.content!.isNotEmpty)
Container(
// Wrap Html in Container to prevent rendering issues
child: Html(
data: article.content,
style: {
"body": Style(
margin: Margins.zero,
padding: HtmlPaddings.zero,
fontSize: FontSize(16),
lineHeight: const LineHeight(1.7),
color: const Color(0xFF1E293B),
Html(
data: article.content,
style: {
"body": Style(
margin: Margins.zero,
padding: HtmlPaddings.zero,
fontSize: FontSize(16),
lineHeight: const LineHeight(1.7),
color: const Color(0xFF1E293B),
),
"h2": Style(
fontSize: FontSize(20),
fontWeight: FontWeight.w600,
color: const Color(0xFF1E293B),
margin: Margins.only(top: 32, bottom: 16),
),
"h3": Style(
fontSize: FontSize(18),
fontWeight: FontWeight.w600,
color: const Color(0xFF1E293B),
margin: Margins.only(top: 24, bottom: 12),
),
"p": Style(
fontSize: FontSize(16),
color: const Color(0xFF1E293B),
lineHeight: const LineHeight(1.7),
margin: Margins.only(bottom: 16),
),
"strong": Style(
fontWeight: FontWeight.w600,
color: const Color(0xFF1E293B),
),
"img": Style(
margin: Margins.symmetric(vertical: 16),
),
"ul": Style(
margin: Margins.only(left: 16, bottom: 16),
),
"ol": Style(
margin: Margins.only(left: 16, bottom: 16),
),
"li": Style(
fontSize: FontSize(16),
color: const Color(0xFF1E293B),
lineHeight: const LineHeight(1.5),
margin: Margins.only(bottom: 8),
),
"blockquote": Style(
backgroundColor: const Color(0xFFF0F9FF),
border: const Border(
left: BorderSide(color: AppColors.primaryBlue, width: 4),
),
"h2": Style(
fontSize: FontSize(20),
fontWeight: FontWeight.w600,
color: const Color(0xFF1E293B),
margin: Margins.only(top: 32, bottom: 16),
),
"h3": Style(
fontSize: FontSize(18),
fontWeight: FontWeight.w600,
color: const Color(0xFF1E293B),
margin: Margins.only(top: 24, bottom: 12),
),
"p": Style(
fontSize: FontSize(16),
color: const Color(0xFF1E293B),
lineHeight: const LineHeight(1.7),
margin: Margins.only(bottom: 16),
),
"strong": Style(
fontWeight: FontWeight.w600,
color: const Color(0xFF1E293B),
),
"img": Style(
margin: Margins.symmetric(vertical: 16),
),
"ul": Style(
margin: Margins.only(left: 16, bottom: 16),
),
"ol": Style(
margin: Margins.only(left: 16, bottom: 16),
),
"li": Style(
fontSize: FontSize(16),
color: const Color(0xFF1E293B),
lineHeight: const LineHeight(1.5),
margin: Margins.only(bottom: 8),
),
"blockquote": Style(
backgroundColor: const Color(0xFFF0F9FF),
border: const Border(
left: BorderSide(color: AppColors.primaryBlue, width: 4),
),
padding: HtmlPaddings.all(16),
margin: Margins.symmetric(vertical: 24),
fontStyle: FontStyle.italic,
),
"div": Style(
margin: Margins.zero,
padding: HtmlPaddings.zero,
),
},
onLinkTap: (url, attributes, element) {
// Handle link taps if needed
if (url != null) {
debugPrint('Link tapped: $url');
}
},
),
padding: HtmlPaddings.all(16),
margin: Margins.symmetric(vertical: 24),
fontStyle: FontStyle.italic,
),
"div": Style(
margin: Margins.zero,
padding: HtmlPaddings.zero,
),
},
onLinkTap: (url, attributes, element) {
// Handle link taps if needed
if (url != null) {
debugPrint('Link tapped: $url');
}
},
),
const SizedBox(height: 32),
@@ -256,9 +255,8 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
/// Build metadata
Widget _buildMetadata(NewsArticle article) {
return Wrap(
return Row(
spacing: 16,
runSpacing: 8,
children: [
// Category badge
Container(
@@ -281,13 +279,13 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
_buildMetaItem(Icons.calendar_today, article.formattedDate),
// Reading time
_buildMetaItem(Icons.schedule, article.readingTimeText),
// _buildMetaItem(Icons.schedule, article.readingTimeText),
// Views
_buildMetaItem(
Icons.visibility,
'${article.formattedViewCount} lượt xem',
),
// _buildMetaItem(
// Icons.visibility,
// '${article.formattedViewCount} lượt xem',
// ),
],
);
}
@@ -362,48 +360,27 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
Widget _buildSocialActions(NewsArticle article) {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
decoration: const BoxDecoration(
border: Border.symmetric(
horizontal: BorderSide(color: const Color(0xFFE2E8F0)),
horizontal: BorderSide(color: Color(0xFFE2E8F0)),
),
),
child: Column(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Engagement stats
Wrap(
spacing: 16,
runSpacing: 8,
children: [
_buildStatItem(Icons.favorite, '${article.likeCount} lượt thích'),
_buildStatItem(
Icons.comment,
'${article.commentCount} bình luận',
),
_buildStatItem(Icons.share, '${article.shareCount} lượt chia sẻ'),
],
_buildActionButton(
icon: _isLiked ? Icons.favorite : Icons.favorite_border,
onPressed: _onLikeTap,
color: _isLiked ? Colors.red : null,
),
const SizedBox(height: 16),
// Action buttons
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildActionButton(
icon: _isLiked ? Icons.favorite : Icons.favorite_border,
onPressed: _onLikeTap,
color: _isLiked ? Colors.red : null,
),
const SizedBox(width: 8),
_buildActionButton(
icon: _isBookmarked ? Icons.bookmark : Icons.bookmark_border,
onPressed: _onBookmarkTap,
color: _isBookmarked ? AppColors.warning : null,
),
const SizedBox(width: 8),
_buildActionButton(icon: Icons.share, onPressed: _onShareTap),
],
const SizedBox(width: 8),
_buildActionButton(
icon: _isBookmarked ? Icons.bookmark : Icons.bookmark_border,
onPressed: _onBookmarkTap,
color: _isBookmarked ? AppColors.warning : null,
),
const SizedBox(width: 8),
_buildActionButton(icon: Icons.share, onPressed: _onShareTap),
],
),
);
@@ -577,21 +554,21 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
/// Handle share tap
void _onShareTap() {
// Copy link to clipboard
Clipboard.setData(
ClipboardData(text: 'https://worker.app/news/${widget.articleId}'),
);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Đã sao chép link bài viết!'),
duration: Duration(seconds: 2),
),
);
// Clipboard.setData(
// ClipboardData(text: 'https://worker.app/news/${widget.articleId}'),
// );
//
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Đã sao chép link bài viết!'),
// duration: Duration(seconds: 2),
// ),
// );
// TODO: Implement native share when share_plus package is added
// Share.share(
// 'Xem bài viết: ${article.title}\nhttps://worker.app/news/${article.id}',
// subject: article.title,
// );
SharePlus.instance.share(
ShareParams(text: 'Xem bài viết: ${ApiConstants.baseUrl}')
);
}
}