Implement replying to event in backend
This commit is contained in:
parent
aa8d3cf8d3
commit
fb35a6ec14
|
@ -53,6 +53,18 @@ else:
|
||||||
|
|
||||||
CryptDict = Dict[str, Any]
|
CryptDict = Dict[str, Any]
|
||||||
|
|
||||||
|
REPLY_FALLBACK = (
|
||||||
|
"<mx-reply>"
|
||||||
|
"<blockquote>"
|
||||||
|
'<a href="https://matrix.to/#/{room_id}/{event_id}">In reply to</a> '
|
||||||
|
'<a href="https://matrix.to/#/{user_id}">{user_id}</a>'
|
||||||
|
"<br>"
|
||||||
|
"{content}"
|
||||||
|
"</blockquote>"
|
||||||
|
"</mx-reply>"
|
||||||
|
"{reply_content}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UploadReturn(NamedTuple):
|
class UploadReturn(NamedTuple):
|
||||||
"""Details for an uploaded file."""
|
"""Details for an uploaded file."""
|
||||||
|
@ -380,7 +392,9 @@ class MatrixClient(nio.AsyncClient):
|
||||||
return {**self.invited_rooms, **self.rooms}
|
return {**self.invited_rooms, **self.rooms}
|
||||||
|
|
||||||
|
|
||||||
async def send_text(self, room_id: str, text: str) -> None:
|
async def send_text(
|
||||||
|
self, room_id: str, text: str, reply_to_event_id: Optional[str] = None,
|
||||||
|
) -> None:
|
||||||
"""Send a markdown `m.text` or `m.notice` (with `/me`) message ."""
|
"""Send a markdown `m.text` or `m.notice` (with `/me`) message ."""
|
||||||
|
|
||||||
from_md = partial(HTML.from_markdown, room_id=room_id)
|
from_md = partial(HTML.from_markdown, room_id=room_id)
|
||||||
|
@ -390,6 +404,8 @@ class MatrixClient(nio.AsyncClient):
|
||||||
escape = True
|
escape = True
|
||||||
text = text[1:]
|
text = text[1:]
|
||||||
|
|
||||||
|
content: Dict[str, Any]
|
||||||
|
|
||||||
if text.startswith("/me ") and not escape:
|
if text.startswith("/me ") and not escape:
|
||||||
event_type = nio.RoomMessageEmote
|
event_type = nio.RoomMessageEmote
|
||||||
text = text[len("/me "): ]
|
text = text[len("/me "): ]
|
||||||
|
@ -406,6 +422,30 @@ class MatrixClient(nio.AsyncClient):
|
||||||
content["format"] = "org.matrix.custom.html"
|
content["format"] = "org.matrix.custom.html"
|
||||||
content["formatted_body"] = to_html
|
content["formatted_body"] = to_html
|
||||||
|
|
||||||
|
if reply_to_event_id:
|
||||||
|
to: Event = \
|
||||||
|
self.models[self.user_id, room_id, "events"][reply_to_event_id]
|
||||||
|
|
||||||
|
content["format"] = "org.matrix.custom.html"
|
||||||
|
content["body"] = f"> <{to.sender_id}> {to.origin_body}"
|
||||||
|
|
||||||
|
to_html = REPLY_FALLBACK.format(
|
||||||
|
room_id = room_id,
|
||||||
|
event_id = reply_to_event_id,
|
||||||
|
user_id = to.sender_id,
|
||||||
|
content =
|
||||||
|
to.origin_formatted_body or html.escape(to.origin_body),
|
||||||
|
|
||||||
|
reply_content = to_html,
|
||||||
|
)
|
||||||
|
|
||||||
|
echo_body = HTML.filter(to_html)
|
||||||
|
content["formatted_body"] = HTML.filter(to_html, outgoing=True)
|
||||||
|
|
||||||
|
content["m.relates_to"] = {
|
||||||
|
"m.in_reply_to": { "event_id": reply_to_event_id },
|
||||||
|
}
|
||||||
|
|
||||||
# Can't use the standard Matrix transaction IDs; they're only visible
|
# Can't use the standard Matrix transaction IDs; they're only visible
|
||||||
# to the sender so our other accounts wouldn't be able to replace
|
# to the sender so our other accounts wouldn't be able to replace
|
||||||
# local echoes by real messages.
|
# local echoes by real messages.
|
||||||
|
@ -414,7 +454,13 @@ class MatrixClient(nio.AsyncClient):
|
||||||
|
|
||||||
mentions = HTML.mentions_in_html(echo_body)
|
mentions = HTML.mentions_in_html(echo_body)
|
||||||
await self._local_echo(
|
await self._local_echo(
|
||||||
room_id, tx_id, event_type, content=echo_body, mentions=mentions,
|
room_id,
|
||||||
|
tx_id,
|
||||||
|
event_type,
|
||||||
|
content = echo_body,
|
||||||
|
mentions = mentions,
|
||||||
|
origin_body = content["body"],
|
||||||
|
origin_formatted_body = content.get("formatted_body") or "",
|
||||||
)
|
)
|
||||||
|
|
||||||
await self._send_message(room_id, content, tx_id)
|
await self._send_message(room_id, content, tx_id)
|
||||||
|
@ -650,7 +696,8 @@ class MatrixClient(nio.AsyncClient):
|
||||||
room_id,
|
room_id,
|
||||||
transaction_id,
|
transaction_id,
|
||||||
event_type,
|
event_type,
|
||||||
inline_content = path.name,
|
inline_content = content["body"],
|
||||||
|
origin_body = content["body"],
|
||||||
media_url = url,
|
media_url = url,
|
||||||
media_title = path.name,
|
media_title = path.name,
|
||||||
media_width = content["info"].get("w", 0),
|
media_width = content["info"].get("w", 0),
|
||||||
|
@ -1389,6 +1436,10 @@ class MatrixClient(nio.AsyncClient):
|
||||||
target_name = target_name,
|
target_name = target_name,
|
||||||
target_avatar = target_avatar,
|
target_avatar = target_avatar,
|
||||||
links = Event.parse_links(content),
|
links = Event.parse_links(content),
|
||||||
|
|
||||||
|
origin_body = getattr(ev, "body", "") or "",
|
||||||
|
origin_formatted_body = getattr(ev, "formatted_body", "") or "",
|
||||||
|
|
||||||
fetch_profile =
|
fetch_profile =
|
||||||
(must_fetch_sender or must_fetch_target)
|
(must_fetch_sender or must_fetch_target)
|
||||||
if override_fetch_profile is None else
|
if override_fetch_profile is None else
|
||||||
|
|
|
@ -219,6 +219,8 @@ class Event(ModelItem):
|
||||||
sender_avatar: str = field()
|
sender_avatar: str = field()
|
||||||
fetch_profile: bool = False
|
fetch_profile: bool = False
|
||||||
|
|
||||||
|
origin_body: str = ""
|
||||||
|
origin_formatted_body: str = ""
|
||||||
content: str = ""
|
content: str = ""
|
||||||
inline_content: str = ""
|
inline_content: str = ""
|
||||||
reason: str = ""
|
reason: str = ""
|
||||||
|
|
|
@ -22,6 +22,7 @@ Item {
|
||||||
property bool ready: Boolean(userInfo && roomInfo)
|
property bool ready: Boolean(userInfo && roomInfo)
|
||||||
property bool longLoading: false
|
property bool longLoading: false
|
||||||
|
|
||||||
|
property string replyToEventId: ""
|
||||||
property string replyToUserId: ""
|
property string replyToUserId: ""
|
||||||
property string replyToDisplayName: ""
|
property string replyToDisplayName: ""
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,11 @@ HColumnPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplyBar {
|
ReplyBar {
|
||||||
|
replyToEventId: chat.replyToEventId
|
||||||
replyToUserId: chat.replyToUserId
|
replyToUserId: chat.replyToUserId
|
||||||
replyToDisplayName: chat.replyToDisplayName
|
replyToDisplayName: chat.replyToDisplayName
|
||||||
onCancel: {
|
onCancel: {
|
||||||
|
chat.replyToEventId = ""
|
||||||
chat.replyToUserId = ""
|
chat.replyToUserId = ""
|
||||||
chat.replyToDisplayName = ""
|
chat.replyToDisplayName = ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ Rectangle {
|
||||||
|
|
||||||
if (textArea.text === "") { return }
|
if (textArea.text === "") { return }
|
||||||
|
|
||||||
const args = [chat.roomId, toSend]
|
const args = [chat.roomId, toSend, chat.replyToEventId]
|
||||||
py.callClientCoro(writingUserId, "send_text", args)
|
py.callClientCoro(writingUserId, "send_text", args)
|
||||||
|
|
||||||
area.clear()
|
area.clear()
|
||||||
|
|
|
@ -9,7 +9,7 @@ InfoBar {
|
||||||
icon.svgName: "reply-to"
|
icon.svgName: "reply-to"
|
||||||
label.textFormat: Text.StyledText
|
label.textFormat: Text.StyledText
|
||||||
label.text:
|
label.text:
|
||||||
replyToUserId ?
|
replyToEventId ?
|
||||||
utils.coloredNameHtml(replyToDisplayName, replyToUserId) :
|
utils.coloredNameHtml(replyToDisplayName, replyToUserId) :
|
||||||
""
|
""
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ InfoBar {
|
||||||
signal cancel()
|
signal cancel()
|
||||||
|
|
||||||
|
|
||||||
|
property string replyToEventId: ""
|
||||||
property string replyToUserId: ""
|
property string replyToUserId: ""
|
||||||
property string replyToDisplayName: ""
|
property string replyToDisplayName: ""
|
||||||
|
|
||||||
|
@ -25,9 +26,6 @@ InfoBar {
|
||||||
backgroundColor: "transparent"
|
backgroundColor: "transparent"
|
||||||
icon.name: "reply-cancel"
|
icon.name: "reply-cancel"
|
||||||
icon.color: theme.colors.negativeBackground
|
icon.color: theme.colors.negativeBackground
|
||||||
// iconItem.small: true
|
|
||||||
// topPadding: 0
|
|
||||||
// bottomPadding: topPadding
|
|
||||||
onClicked: cancel()
|
onClicked: cancel()
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
|
@ -233,6 +233,7 @@ HColumnLayout {
|
||||||
text: qsTr("Reply")
|
text: qsTr("Reply")
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
|
chat.replyToEventId = model.id
|
||||||
chat.replyToUserId = model.sender_id
|
chat.replyToUserId = model.sender_id
|
||||||
chat.replyToDisplayName = model.sender_name
|
chat.replyToDisplayName = model.sender_name
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user