feat: suporte a tabelas markdown nas legendas, remoção de borda de imagens e separação de comentários no mural
Some checks failed
Main Deploy Workflow / deploy_web (push) Has been cancelled
Main Deploy Workflow / deploy_playstore_internal (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
2026-09-15 17:24:18 -03:00
parent 43e0dc177c
commit ab8637bf6a
6 changed files with 157 additions and 32 deletions

View File

@@ -10,11 +10,14 @@ import 'package:collection/collection.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:file_picker/file_picker.dart';
import 'package:html/parser.dart' show parseFragment;
import 'package:markdown/markdown.dart' show ExtensionSet, markdownToHtml;
import 'package:tatchat/config/setting_keys.dart';
import 'package:tatchat/config/themes.dart';
import 'package:tatchat/l10n/l10n.dart';
import 'package:tatchat/pages/chat/chat_view.dart';
import 'package:tatchat/pages/chat/event_info_dialog.dart';
import 'package:tatchat/pages/chat/edit_media_caption_dialog.dart';
import 'package:tatchat/pages/chat/start_poll_bottom_sheet.dart';
import 'package:tatchat/pages/chat/trust_user_key_dialog.dart';
import 'package:tatchat/pages/chat/utils/web_file_to_x_file.dart';
@@ -1314,6 +1317,16 @@ class ChatController extends State<ChatPageWithRoom>
final timeline = this.timeline;
if (timeline == null) return;
if (const {
MessageTypes.Image,
MessageTypes.Video,
MessageTypes.Audio,
MessageTypes.File,
}.contains(event.messageType)) {
_startEditingMediaCaption(event, clearSelection: clearSelection);
return;
}
final client = currentRoomBundle.firstWhere(
(c) => c?.userID == event.senderId,
orElse: () => null,
@@ -1336,6 +1349,33 @@ class ChatController extends State<ChatPageWithRoom>
inputFocus.requestFocus();
}
Future<void> _startEditingMediaCaption(
Event event, {
bool clearSelection = false,
}) async {
final timeline = this.timeline;
if (timeline == null) return;
if (clearSelection) setState(() => selectedEvents.clear());
final caption = event.getDisplayEvent(timeline).body;
final result = await showEditMediaCaptionDialog(
context,
initialCaption: caption,
);
if (result == null) return;
final html = markdownToHtml(
result,
extensionSet: ExtensionSet.gitHubFlavored,
);
final content = Map<String, Object?>.of(event.content)
..remove('m.relates_to')
..['body'] = result;
if (parseFragment(html).text != result) {
content['format'] = 'org.matrix.custom.html';
content['formatted_body'] = html;
}
await room.sendEvent(content, editEventId: event.eventId);
}
void editSelectedEventAction() {
_startEditingEvent(selectedEvents.first, clearSelection: true);
}