kopia lustrzana https://gitlab.com/mysocialportal/relatica
				
				
				
			
		
			
				
	
	
		
			170 wiersze
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			170 wiersze
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Dart
		
	
	
| import 'package:html/dom.dart';
 | |
| import 'package:html/parser.dart';
 | |
| import 'package:path/path.dart' as p;
 | |
| 
 | |
| import '../globals.dart';
 | |
| import '../services/auth_service.dart';
 | |
| import 'network_utils.dart';
 | |
| 
 | |
| String htmlToSimpleText(String htmlContentFragment) {
 | |
|   try {
 | |
|     final dom = parseFragment(htmlContentFragment);
 | |
|     final segments = dom.nodes
 | |
|         .map((n) => n is Element ? n.elementToEditText() : n.nodeToEditText())
 | |
|         .toList();
 | |
|     return segments.join('');
 | |
|   } catch (e) {
 | |
|     return htmlContentFragment;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void _updateSwapTagLinks(Node node, List<String> tags) {
 | |
|   if (node is Element) {
 | |
|     if (node.attributes.containsKey('href') &&
 | |
|         (node.attributes['class']?.contains('hashtag') ?? false) &&
 | |
|         node.attributes['rel'] == 'tag') {
 | |
|       final url = Uri.parse(node.attributes['href'] ?? '');
 | |
|       late final String tag;
 | |
|       final pathEnd = p.split(url.path).last;
 | |
|       if (pathEnd == 'search' && url.queryParameters.containsKey('tag')) {
 | |
|         tag = url.queryParameters['search']!;
 | |
|       } else {
 | |
|         tag = pathEnd;
 | |
|       }
 | |
|       final tagLowercase = tag.toLowerCase();
 | |
|       final hasExpectedTag = tags
 | |
|           .firstWhere((t) => t.toLowerCase() == tagLowercase, orElse: () => '')
 | |
|           .isNotEmpty;
 | |
|       if (hasExpectedTag) {
 | |
|         final profile = getIt<AccountsService>().currentProfile;
 | |
|         final newTagUrl = generateTagUrlFromProfile(profile, tag);
 | |
|         print(node.attributes['href']);
 | |
|         node.attributes['href'] = newTagUrl.toString();
 | |
|         print(node.attributes['href']);
 | |
|       }
 | |
|     }
 | |
|     for (var n in node.nodes) {
 | |
|       _updateSwapTagLinks(n, tags);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| String htmlWithTagLinkSwap(String htmlContentFragment, List<String> tags) {
 | |
|   try {
 | |
|     final dom = parseFragment(htmlContentFragment);
 | |
|     for (var n in dom.nodes) {
 | |
|       _updateSwapTagLinks(n, tags);
 | |
|     }
 | |
| 
 | |
|     final result = dom.outerHtml;
 | |
|     return result;
 | |
|   } catch (e) {
 | |
|     return htmlContentFragment;
 | |
|   }
 | |
| }
 | |
| 
 | |
| extension NodeTextConverter on Node {
 | |
|   String nodeToEditText() {
 | |
|     if (nodes.isEmpty) {
 | |
|       final stringWithQuotes = toString();
 | |
|       final start = stringWithQuotes.startsWith('"') ? 1 : 0;
 | |
|       final end = stringWithQuotes.endsWith('"')
 | |
|           ? stringWithQuotes.length - 1
 | |
|           : stringWithQuotes.length;
 | |
|       return stringWithQuotes.substring(start, end);
 | |
|     }
 | |
| 
 | |
|     final convertedNodes = nodes
 | |
|         .map((n) => n is Element ? n.elementToEditText() : n.nodeToEditText())
 | |
|         .toList();
 | |
|     return convertedNodes.join('');
 | |
|   }
 | |
| }
 | |
| 
 | |
| extension ElementTextConverter on Element {
 | |
|   String elementToEditText({int depth = 0}) {
 | |
|     late final String innerText;
 | |
|     late final String startText;
 | |
|     late final String endText;
 | |
|     switch (localName) {
 | |
|       case 'a':
 | |
|         startText = '';
 | |
|         innerText = htmlLinkToString();
 | |
|         endText = '';
 | |
|         break;
 | |
|       case 'br':
 | |
|         startText = '';
 | |
|         innerText = '';
 | |
|         endText = '\n';
 | |
|         break;
 | |
|       case 'p':
 | |
|         startText = '';
 | |
|         innerText = buildInnerText(depth);
 | |
|         endText = '\n';
 | |
|         break;
 | |
|       case 'em':
 | |
|         startText = '*';
 | |
|         innerText = buildInnerText(depth);
 | |
|         endText = '*';
 | |
|         break;
 | |
|       case 'strong':
 | |
|         startText = '**';
 | |
|         innerText = buildInnerText(depth);
 | |
|         endText = '**';
 | |
|         break;
 | |
|       case 'li':
 | |
|         startText = '\n${buildTabs(depth)}- ';
 | |
|         innerText = buildInnerText(depth);
 | |
|         endText = '';
 | |
|         break;
 | |
|       case 'ul':
 | |
|         startText = '';
 | |
|         innerText = buildInnerText(depth + 1);
 | |
|         endText = '';
 | |
|         break;
 | |
|       default:
 | |
|         startText = '<$localName>';
 | |
|         innerText = buildInnerText(depth);
 | |
|         endText = '</$localName>';
 | |
|     }
 | |
| 
 | |
|     return '$startText$innerText$endText';
 | |
|   }
 | |
| 
 | |
|   String htmlLinkToString() {
 | |
|     final attrs = attributes['class'] ?? '';
 | |
|     if (attrs.contains('hashtag')) {
 | |
|       return text;
 | |
|     }
 | |
| 
 | |
|     if (attrs.contains('mention')) {
 | |
|       final uri = Uri.parse(attributes['href'] ?? '');
 | |
|       final host = uri.host;
 | |
|       final username = text;
 | |
|       return '$username@$host';
 | |
|     }
 | |
| 
 | |
|     return attributes['href'] ?? 'No link found';
 | |
|   }
 | |
| 
 | |
|   String buildInnerText(int depth) {
 | |
|     if (nodes.isEmpty) {
 | |
|       return '';
 | |
|     }
 | |
| 
 | |
|     final convertedNodes = nodes
 | |
|         .map((n) => n is Element
 | |
|             ? n.elementToEditText(depth: depth)
 | |
|             : n.nodeToEditText())
 | |
|         .toList();
 | |
|     return convertedNodes.join('');
 | |
|   }
 | |
| 
 | |
|   String buildTabs(int depth) => depth == 0
 | |
|       ? ''
 | |
|       : List.generate(
 | |
|           depth,
 | |
|           (index) => '  ',
 | |
|         ).join('');
 | |
| }
 |