update
This commit is contained in:
@@ -176,7 +176,7 @@ SPEC CHECKSUMS:
|
|||||||
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
|
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
|
||||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
|
file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49
|
||||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||||
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
|
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
|
||||||
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
|
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
|
||||||
@@ -196,7 +196,7 @@ SPEC CHECKSUMS:
|
|||||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
|
SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
|
||||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
|
||||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||||
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
|
||||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Worker</string>
|
<string>DBIZ Partner</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_html/flutter_html.dart';
|
import 'package:flutter_html/flutter_html.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:go_router/go_router.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/constants/ui_constants.dart';
|
||||||
import 'package:worker/core/theme/colors.dart';
|
import 'package:worker/core/theme/colors.dart';
|
||||||
import 'package:worker/features/news/domain/entities/news_article.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
|
// Article Body - Render HTML content
|
||||||
if (article.content != null && article.content!.isNotEmpty)
|
if (article.content != null && article.content!.isNotEmpty)
|
||||||
Container(
|
Html(
|
||||||
// Wrap Html in Container to prevent rendering issues
|
data: article.content,
|
||||||
child: Html(
|
style: {
|
||||||
data: article.content,
|
"body": Style(
|
||||||
style: {
|
margin: Margins.zero,
|
||||||
"body": Style(
|
padding: HtmlPaddings.zero,
|
||||||
margin: Margins.zero,
|
fontSize: FontSize(16),
|
||||||
padding: HtmlPaddings.zero,
|
lineHeight: const LineHeight(1.7),
|
||||||
fontSize: FontSize(16),
|
color: const Color(0xFF1E293B),
|
||||||
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(
|
padding: HtmlPaddings.all(16),
|
||||||
fontSize: FontSize(20),
|
margin: Margins.symmetric(vertical: 24),
|
||||||
fontWeight: FontWeight.w600,
|
fontStyle: FontStyle.italic,
|
||||||
color: const Color(0xFF1E293B),
|
),
|
||||||
margin: Margins.only(top: 32, bottom: 16),
|
"div": Style(
|
||||||
),
|
margin: Margins.zero,
|
||||||
"h3": Style(
|
padding: HtmlPaddings.zero,
|
||||||
fontSize: FontSize(18),
|
),
|
||||||
fontWeight: FontWeight.w600,
|
},
|
||||||
color: const Color(0xFF1E293B),
|
onLinkTap: (url, attributes, element) {
|
||||||
margin: Margins.only(top: 24, bottom: 12),
|
// Handle link taps if needed
|
||||||
),
|
if (url != null) {
|
||||||
"p": Style(
|
debugPrint('Link tapped: $url');
|
||||||
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');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
@@ -256,9 +255,8 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
|
|||||||
|
|
||||||
/// Build metadata
|
/// Build metadata
|
||||||
Widget _buildMetadata(NewsArticle article) {
|
Widget _buildMetadata(NewsArticle article) {
|
||||||
return Wrap(
|
return Row(
|
||||||
spacing: 16,
|
spacing: 16,
|
||||||
runSpacing: 8,
|
|
||||||
children: [
|
children: [
|
||||||
// Category badge
|
// Category badge
|
||||||
Container(
|
Container(
|
||||||
@@ -281,13 +279,13 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
|
|||||||
_buildMetaItem(Icons.calendar_today, article.formattedDate),
|
_buildMetaItem(Icons.calendar_today, article.formattedDate),
|
||||||
|
|
||||||
// Reading time
|
// Reading time
|
||||||
_buildMetaItem(Icons.schedule, article.readingTimeText),
|
// _buildMetaItem(Icons.schedule, article.readingTimeText),
|
||||||
|
|
||||||
// Views
|
// Views
|
||||||
_buildMetaItem(
|
// _buildMetaItem(
|
||||||
Icons.visibility,
|
// Icons.visibility,
|
||||||
'${article.formattedViewCount} lượt xem',
|
// '${article.formattedViewCount} lượt xem',
|
||||||
),
|
// ),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -362,48 +360,27 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
|
|||||||
Widget _buildSocialActions(NewsArticle article) {
|
Widget _buildSocialActions(NewsArticle article) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
decoration: BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
border: Border.symmetric(
|
border: Border.symmetric(
|
||||||
horizontal: BorderSide(color: const Color(0xFFE2E8F0)),
|
horizontal: BorderSide(color: Color(0xFFE2E8F0)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
// Engagement stats
|
_buildActionButton(
|
||||||
Wrap(
|
icon: _isLiked ? Icons.favorite : Icons.favorite_border,
|
||||||
spacing: 16,
|
onPressed: _onLikeTap,
|
||||||
runSpacing: 8,
|
color: _isLiked ? Colors.red : null,
|
||||||
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ẻ'),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
const SizedBox(height: 16),
|
_buildActionButton(
|
||||||
|
icon: _isBookmarked ? Icons.bookmark : Icons.bookmark_border,
|
||||||
// Action buttons
|
onPressed: _onBookmarkTap,
|
||||||
Row(
|
color: _isBookmarked ? AppColors.warning : null,
|
||||||
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: Icons.share, onPressed: _onShareTap),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -577,21 +554,21 @@ class _NewsDetailPageState extends ConsumerState<NewsDetailPage> {
|
|||||||
/// Handle share tap
|
/// Handle share tap
|
||||||
void _onShareTap() {
|
void _onShareTap() {
|
||||||
// Copy link to clipboard
|
// Copy link to clipboard
|
||||||
Clipboard.setData(
|
// Clipboard.setData(
|
||||||
ClipboardData(text: 'https://worker.app/news/${widget.articleId}'),
|
// ClipboardData(text: 'https://worker.app/news/${widget.articleId}'),
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
// ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
// const SnackBar(
|
||||||
content: Text('Đã sao chép link bài viết!'),
|
// content: Text('Đã sao chép link bài viết!'),
|
||||||
duration: Duration(seconds: 2),
|
// duration: Duration(seconds: 2),
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
|
|
||||||
// TODO: Implement native share when share_plus package is added
|
// TODO: Implement native share when share_plus package is added
|
||||||
// Share.share(
|
SharePlus.instance.share(
|
||||||
// 'Xem bài viết: ${article.title}\nhttps://worker.app/news/${article.id}',
|
ShareParams(text: 'Xem bài viết: ${ApiConstants.baseUrl}')
|
||||||
// subject: article.title,
|
);
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
pubspec.lock
16
pubspec.lock
@@ -413,10 +413,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
sha256: "825aec673606875c33cd8d3c4083f1a3c3999015a84178b317b7ef396b7384f3"
|
sha256: ab13ae8ef5580a411c458d6207b6774a6c237d77ac37011b13994879f68a8810
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.7"
|
version: "8.3.7"
|
||||||
file_selector_linux:
|
file_selector_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1160,18 +1160,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: share_plus
|
name: share_plus
|
||||||
sha256: ef3489a969683c4f3d0239010cc8b7a2a46543a8d139e111c06c558875083544
|
sha256: "14c8860d4de93d3a7e53af51bff479598c4e999605290756bbbe45cf65b37840"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.0.0"
|
version: "12.0.1"
|
||||||
share_plus_platform_interface:
|
share_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: share_plus_platform_interface
|
name: share_plus_platform_interface
|
||||||
sha256: "0f9e4418835d1b2c3ae78fdb918251959106cefdbc4dd43526e182f80e82f6d4"
|
sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "6.1.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -1565,10 +1565,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web
|
name: web
|
||||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "1.1.1"
|
||||||
web_socket:
|
web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.0.0+1
|
version: 1.0.0+3
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.2
|
sdk: ^3.9.2
|
||||||
@@ -63,9 +63,10 @@ dependencies:
|
|||||||
qr_flutter: ^4.1.0
|
qr_flutter: ^4.1.0
|
||||||
mobile_scanner: ^5.2.3
|
mobile_scanner: ^5.2.3
|
||||||
|
|
||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
intl: ^0.20.0
|
intl: ^0.20.0
|
||||||
share_plus: ^9.0.0
|
share_plus: ^12.0.1
|
||||||
image_picker: ^1.1.2
|
image_picker: ^1.1.2
|
||||||
file_picker: ^8.0.0
|
file_picker: ^8.0.0
|
||||||
url_launcher: ^6.3.0
|
url_launcher: ^6.3.0
|
||||||
|
|||||||
Reference in New Issue
Block a user