diff --git a/lib/core/misc/html_utils/html_to_plain_text.dart b/lib/core/misc/html_utils/html_to_plain_text.dart index c5d5eb14..6d2866fd 100644 --- a/lib/core/misc/html_utils/html_to_plain_text.dart +++ b/lib/core/misc/html_utils/html_to_plain_text.dart @@ -1,11 +1,87 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright 2025 BitCodersNN -import 'package:html/parser.dart'; +import 'package:html/dom.dart' as dom; +import 'package:html/parser.dart' as parser; import 'package:html_unescape/html_unescape.dart'; +void _processNode( + dom.Node node, + StringBuffer buffer, + Set blockTags, +) { + if (node is dom.Text) { + final text = node.text.replaceAll(RegExp(r'\s+'), ' ').trim(); + if (text.isNotEmpty) { + buffer.write('$text '); + } + } else if (node is dom.Element) { + final tagName = node.localName?.toLowerCase(); + + if (tagName == 'a') { + final href = node.attributes['href']; + if (href != null && href.trim().isNotEmpty) { + buffer.write(href); + } else { + for (final child in node.nodes) { + _processNode(child, buffer, blockTags); + } + } + } else { + for (final child in node.nodes) { + _processNode(child, buffer, blockTags); + } + } + + if (blockTags.contains(tagName)) { + buffer.write('\n'); + } + } +} + +String _getElementTextWithFormatting(dom.Element element) { + final buffer = StringBuffer(); + final blockTags = { + 'br', + 'p', + 'div', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'li', + 'tr', + 'pre', + 'blockquote', + 'hr', + 'ul', + 'ol', + 'dl', + 'section', + 'article', + 'aside', + 'header', + 'footer', + 'main', + }; + + _processNode(element, buffer, blockTags); + + return buffer + .toString() + .replaceAll(RegExp(r'[ \t]*\n[ \t]*'), '\n') + .replaceAll(RegExp(r'\n{3,}'), '\n\n') + .trim(); +} + String htmlToPlainText(String htmlText) { final unescaped = HtmlUnescape().convert(htmlText); - final document = parse(unescaped); - return document.body?.text ?? ''; + final document = parser.parse(unescaped); + final body = document.body; + if (body != null) { + return _getElementTextWithFormatting(body); + } + return ''; } diff --git a/lib/ui/views/main_page/feed/widgets/feed_post.dart b/lib/ui/views/main_page/feed/widgets/feed_post.dart index 29285b32..c2ecaaee 100644 --- a/lib/ui/views/main_page/feed/widgets/feed_post.dart +++ b/lib/ui/views/main_page/feed/widgets/feed_post.dart @@ -291,7 +291,7 @@ class _FeedPostState extends State { ShareParams( files: xFiles.isEmpty ? null : xFiles, text: - 'Из ленты Портала ННГУ (автор ${model.profileViewModel.fullname}):\n${htmlToPlainText(model.postText)}', + '${htmlToPlainText(model.postText)}\n\nИсточник: Портал ННГУ\nАвтор: ${model.profileViewModel.fullname}', ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 86f6c3d1..847790b9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: unn_mobile description: A mobile application for UNN Portal website publish_to: 'none' -version: 0.6.0+372 +version: 0.6.0+373 environment: sdk: '>=3.1.2 <4.0.0'