Implement replying to event in backend
This commit is contained in:
parent
aa8d3cf8d3
commit
fb35a6ec14
|
@ -53,6 +53,18 @@ else:
|
|||
|
||||
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):
|
||||
"""Details for an uploaded file."""
|
||||
|
@ -380,7 +392,9 @@ class MatrixClient(nio.AsyncClient):
|
|||
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 ."""
|
||||
|
||||
from_md = partial(HTML.from_markdown, room_id=room_id)
|
||||
|
@ -390,6 +404,8 @@ class MatrixClient(nio.AsyncClient):
|
|||
escape = True
|
||||
text = text[1:]
|
||||
|
||||
content: Dict[str, Any]
|
||||
|
||||
if text.startswith("/me ") and not escape:
|
||||
event_type = nio.RoomMessageEmote
|
||||
text = text[len("/me "): ]
|
||||
|
@ -406,6 +422,30 @@ class MatrixClient(nio.AsyncClient):
|
|||
content["format"] = "org.matrix.custom.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
|
||||
# to the sender so our other accounts wouldn't be able to replace
|
||||
# local echoes by real messages.
|
||||
|
@ -414,7 +454,13 @@ class MatrixClient(nio.AsyncClient):
|
|||
|
||||
mentions = HTML.mentions_in_html(echo_body)
|
||||
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)
|
||||
|
@ -650,7 +696,8 @@ class MatrixClient(nio.AsyncClient):
|
|||
room_id,
|
||||
transaction_id,
|
||||
event_type,
|
||||
inline_content = path.name,
|
||||
inline_content = content["body"],
|
||||
origin_body = content["body"],
|
||||
media_url = url,
|
||||
media_title = path.name,
|
||||
media_width = content["info"].get("w", 0),
|
||||
|
@ -1389,6 +1436,10 @@ class MatrixClient(nio.AsyncClient):
|
|||
target_name = target_name,
|
||||
target_avatar = target_avatar,
|
||||
links = Event.parse_links(content),
|
||||
|
||||
origin_body = getattr(ev, "body", "") or "",
|
||||
origin_formatted_body = getattr(ev, "formatted_body", "") or "",
|
||||
|
||||
fetch_profile =
|
||||
(must_fetch_sender or must_fetch_target)
|
||||
if override_fetch_profile is None else
|
||||
|
|
|
@ -219,11 +219,13 @@ class Event(ModelItem):
|
|||
sender_avatar: str = field()
|
||||
fetch_profile: bool = False
|
||||
|
||||
content: str = ""
|
||||
inline_content: str = ""
|
||||
reason: str = ""
|
||||
links: List[str] = field(default_factory=list)
|
||||
mentions: List[Tuple[str, str]] = field(default_factory=list)
|
||||
origin_body: str = ""
|
||||
origin_formatted_body: str = ""
|
||||
content: str = ""
|
||||
inline_content: str = ""
|
||||
reason: str = ""
|
||||
links: List[str] = field(default_factory=list)
|
||||
mentions: List[Tuple[str, str]] = field(default_factory=list)
|
||||
|
||||
type_specifier: TypeSpecifier = TypeSpecifier.Unset
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ Item {
|
|||
property bool ready: Boolean(userInfo && roomInfo)
|
||||
property bool longLoading: false
|
||||
|
||||
property string replyToEventId: ""
|
||||
property string replyToUserId: ""
|
||||
property string replyToDisplayName: ""
|
||||
|
||||
|
|
|
@ -69,9 +69,11 @@ HColumnPage {
|
|||
}
|
||||
|
||||
ReplyBar {
|
||||
replyToEventId: chat.replyToEventId
|
||||
replyToUserId: chat.replyToUserId
|
||||
replyToDisplayName: chat.replyToDisplayName
|
||||
onCancel: {
|
||||
chat.replyToEventId = ""
|
||||
chat.replyToUserId = ""
|
||||
chat.replyToDisplayName = ""
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ Rectangle {
|
|||
|
||||
if (textArea.text === "") { return }
|
||||
|
||||
const args = [chat.roomId, toSend]
|
||||
const args = [chat.roomId, toSend, chat.replyToEventId]
|
||||
py.callClientCoro(writingUserId, "send_text", args)
|
||||
|
||||
area.clear()
|
||||
|
|
|
@ -9,7 +9,7 @@ InfoBar {
|
|||
icon.svgName: "reply-to"
|
||||
label.textFormat: Text.StyledText
|
||||
label.text:
|
||||
replyToUserId ?
|
||||
replyToEventId ?
|
||||
utils.coloredNameHtml(replyToDisplayName, replyToUserId) :
|
||||
""
|
||||
|
||||
|
@ -17,6 +17,7 @@ InfoBar {
|
|||
signal cancel()
|
||||
|
||||
|
||||
property string replyToEventId: ""
|
||||
property string replyToUserId: ""
|
||||
property string replyToDisplayName: ""
|
||||
|
||||
|
@ -25,9 +26,6 @@ InfoBar {
|
|||
backgroundColor: "transparent"
|
||||
icon.name: "reply-cancel"
|
||||
icon.color: theme.colors.negativeBackground
|
||||
// iconItem.small: true
|
||||
// topPadding: 0
|
||||
// bottomPadding: topPadding
|
||||
onClicked: cancel()
|
||||
|
||||
Layout.fillHeight: true
|
||||
|
|
|
@ -233,6 +233,7 @@ HColumnLayout {
|
|||
text: qsTr("Reply")
|
||||
|
||||
onTriggered: {
|
||||
chat.replyToEventId = model.id
|
||||
chat.replyToUserId = model.sender_id
|
||||
chat.replyToDisplayName = model.sender_name
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user