diff --git a/TODO.md b/TODO.md index 99ca0db3..3f4801e5 100644 --- a/TODO.md +++ b/TODO.md @@ -18,6 +18,7 @@ - Horrible performance for big rooms - UI + - Need to make events and messages avatars the same size - Show error box if uploading avatar fails - EditAccount page: - Device settings diff --git a/src/python/html_filter.py b/src/python/html_filter.py index ecc2605b..985f3609 100644 --- a/src/python/html_filter.py +++ b/src/python/html_filter.py @@ -36,8 +36,12 @@ class HtmlFilter: return self.filter(self._markdown_to_html(text)) + def from_markdown_inline(self, text: str) -> str: + return self.filter_inline(self._markdown_to_html(text)) + + def filter_inline(self, html: str) -> str: - return self._inline_sanitizer.sanitize(html) + return self._inline_sanitizer.sanitize(html).strip("\n") def filter(self, html: str) -> str: diff --git a/src/python/matrix_client.py b/src/python/matrix_client.py index 5af23af9..ee19263c 100644 --- a/src/python/matrix_client.py +++ b/src/python/matrix_client.py @@ -155,15 +155,27 @@ class MatrixClient(nio.AsyncClient): async def send_markdown(self, room_id: str, text: str) -> None: - content = {"body": text, "msgtype": "m.text"} - to_html = HTML_FILTER.from_markdown(text) + escape = False + if text.startswith("//") or text.startswith(r"\/"): + escape = True + text = text[1:] + + if text.startswith("/me ") and not escape: + event_type = nio.RoomMessageEmote + text = text[len("/me "): ] + content = {"body": text, "msgtype": "m.emote"} + to_html = HTML_FILTER.from_markdown_inline(text) + else: + event_type = nio.RoomMessageText + content = {"body": text, "msgtype": "m.text"} + to_html = HTML_FILTER.from_markdown(text) if to_html not in (text, f"

{text}

"): content["format"] = "org.matrix.custom.html" content["formatted_body"] = to_html TimelineMessageReceived( - event_type = nio.RoomMessageText, + event_type = event_type, room_id = room_id, event_id = f"local_echo.{uuid4()}", sender_id = self.user_id, diff --git a/src/qml/Chat/Timeline/EventDelegate.qml b/src/qml/Chat/Timeline/EventDelegate.qml index 2e5b02c8..3a29c352 100644 --- a/src/qml/Chat/Timeline/EventDelegate.qml +++ b/src/qml/Chat/Timeline/EventDelegate.qml @@ -36,6 +36,13 @@ Column { model.date && previousItem && previousItem.eventType && previousItem.date && Utils.eventIsMessage(previousItem) == Utils.eventIsMessage(model) && + + // RoomMessageEmote are shown inline-style + ! (previousItem.eventType == "RoomMessageEmote" && + model.eventType != "RoomMessageEmote") && + ! (previousItem.eventType != "RoomMessageEmote" && + model.eventType == "RoomMessageEmote") && + ! talkBreak && ! dayBreak && previousItem.senderId === model.senderId && diff --git a/src/qml/SidePane/RoomDelegate.qml b/src/qml/SidePane/RoomDelegate.qml index 370bdbf4..170789ac 100644 --- a/src/qml/SidePane/RoomDelegate.qml +++ b/src/qml/SidePane/RoomDelegate.qml @@ -51,7 +51,8 @@ HInteractiveRectangle { function getText(ev) { if (! ev) { return "" } - if (! Utils.eventIsMessage(ev)) { + if (ev.eventType == "RoomMessageEmote" || + ! Utils.eventIsMessage(ev)) { return Utils.translatedEventContent(ev) }