Merge branch 'main' into main

This commit is contained in:
Andriy Kushnir 2025-12-03 09:20:14 +02:00 committed by GitHub
commit 50aed3ab93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 27 additions and 26 deletions

View file

@ -86,10 +86,10 @@ class HtmlMessage extends StatelessWidget {
'rt', 'rt',
'html', 'html',
'body', 'body',
// Workaround for https://github.com/krille-chan/fluffychat/issues/507
'tg-forward',
}; };
static const Set<String> ignoredHtmlTags = {'mx-reply'};
/// We add line breaks before these tags: /// We add line breaks before these tags:
static const Set<String> blockHtmlTags = { static const Set<String> blockHtmlTags = {
'p', 'p',
@ -156,8 +156,13 @@ class HtmlMessage extends StatelessWidget {
// We must not render elements nested more than 100 elements deep: // We must not render elements nested more than 100 elements deep:
if (depth >= 100) return const TextSpan(); if (depth >= 100) return const TextSpan();
// This is a text node, so we render it as text: if (node is dom.Element &&
if (node is! dom.Element) { ignoredHtmlTags.contains(node.localName?.toLowerCase())) {
return const TextSpan();
}
// This is a text node or not permitted node, so we render it as text:
if (node is! dom.Element || !allowedHtmlTags.contains(node.localName)) {
var text = node.text ?? ''; var text = node.text ?? '';
// Single linebreak nodes between Elements are ignored: // Single linebreak nodes between Elements are ignored:
if (text == '\n') text = ''; if (text == '\n') text = '';
@ -170,9 +175,6 @@ class HtmlMessage extends StatelessWidget {
); );
} }
// We must not render tags which are not in the allow list:
if (!allowedHtmlTags.contains(node.localName)) return const TextSpan();
switch (node.localName) { switch (node.localName) {
case 'br': case 'br':
return const TextSpan(text: '\n'); return const TextSpan(text: '\n');
@ -261,13 +263,15 @@ class HtmlMessage extends StatelessWidget {
child: Text.rich( child: Text.rich(
TextSpan( TextSpan(
children: [ children: [
if (node.parent?.localName == 'ul') if (!isCheckbox) ...[
const TextSpan(text: ''), if (node.parent?.localName == 'ul')
if (node.parent?.localName == 'ol') const TextSpan(text: ''),
TextSpan( if (node.parent?.localName == 'ol')
text: TextSpan(
'${(node.parent?.nodes.whereType<dom.Element>().toList().indexOf(node) ?? 0) + (int.tryParse(node.parent?.attributes['start'] ?? '1') ?? 1)}. ', text:
), '${(node.parent?.nodes.whereType<dom.Element>().toList().indexOf(node) ?? 0) + (int.tryParse(node.parent?.attributes['start'] ?? '1') ?? 1)}. ',
),
],
if (node.className == 'task-list-item') if (node.className == 'task-list-item')
WidgetSpan( WidgetSpan(
child: Padding( child: Padding(

View file

@ -241,7 +241,7 @@ class MessageContent extends StatelessWidget {
} }
var html = AppSettings.renderHtml.value && event.isRichMessage var html = AppSettings.renderHtml.value && event.isRichMessage
? event.formattedText ? event.formattedText
: event.body; : event.body.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
if (event.messageType == MessageTypes.Emote) { if (event.messageType == MessageTypes.Emote) {
html = '* $html'; html = '* $html';
} }

View file

@ -27,6 +27,7 @@ packageLicenseOverride:
platform_detect: Apache-2.0 platform_detect: Apache-2.0
rxdart: Apache-2.0 rxdart: Apache-2.0
flutter_new_badger: MIT flutter_new_badger: MIT
sqlcipher_flutter_libs: MIT
# flutter's internal packages # flutter's internal packages
flutter_driver: BSD-3-Clause flutter_driver: BSD-3-Clause

View file

@ -1015,12 +1015,11 @@ packages:
license_checker: license_checker:
dependency: "direct dev" dependency: "direct dev"
description: description:
path: "." name: license_checker
ref: HEAD sha256: "8a35b6946e50811e070ac6fe4717ee431cd1a334e080df2116956b54b0bb0d0f"
resolved-ref: "38a65ff5b4b65db092b11dad999081388f75ece8" url: "https://pub.dev"
url: "https://github.com/krille-chan/license_checker.git" source: hosted
source: git version: "1.6.2"
version: "1.6.0"
linkify: linkify:
dependency: "direct main" dependency: "direct main"
description: description:

View file

@ -92,9 +92,7 @@ dev_dependencies:
import_sorter: ^4.6.0 import_sorter: ^4.6.0
integration_test: integration_test:
sdk: flutter sdk: flutter
# Waiting for https://github.com/rufman/license_checker/pull/47 license_checker: ^1.6.2
license_checker:
git: https://github.com/krille-chan/license_checker.git
translations_cleaner: ^0.0.5 translations_cleaner: ^0.0.5
import_sorter: import_sorter:

View file

@ -8,8 +8,7 @@ import 'utils/test_client.dart';
void main() async { void main() async {
test('Check for missing /command hints', () async { test('Check for missing /command hints', () async {
final translated = final translated =
jsonDecode(File('lib/l10n/intl_en.arb').readAsStringSync()) jsonDecode(File('lib/l10n/intl_en.arb').readAsStringSync()).keys
.keys
.where((String k) => k.startsWith('commandHint_')) .where((String k) => k.startsWith('commandHint_'))
.map((k) => k.replaceFirst('commandHint_', '')); .map((k) => k.replaceFirst('commandHint_', ''));
final commands = (await prepareTestClient()).commands.keys; final commands = (await prepareTestClient()).commands.keys;