@@ -37,6 +37,41 @@ function fallbackPrefix(msgtype) {
37
37
return msgtype === "m.emote" ? "* " : "" ;
38
38
}
39
39
40
+ function _parsePlainBody ( plainBody ) {
41
+ // Strip any existing reply fallback and return an array of lines.
42
+
43
+ const bodyLines = plainBody . trim ( ) . split ( "\n" ) ;
44
+
45
+ return bodyLines
46
+ . map ( ( elem , index , array ) => {
47
+ if ( index > 0 && array [ index - 1 ] [ 0 ] !== '>' ) {
48
+ // stop stripping the fallback at the first line of non-fallback text
49
+ return elem ;
50
+ } else if ( elem [ 0 ] === '>' && elem [ 1 ] === ' ' ) {
51
+ return null ;
52
+ } else {
53
+ return elem ;
54
+ }
55
+ } )
56
+ . filter ( ( elem ) => elem !== null )
57
+ // Join, trim, and split to remove any line breaks that were left between the
58
+ // fallback and the actual message body. Don't use trim() because that would
59
+ // also remove any other whitespace at the beginning of the message that the
60
+ // user added intentionally.
61
+ . join ( '\n' )
62
+ . replace ( / ^ \n + | \n + $ / g, '' )
63
+ . split ( '\n' )
64
+ }
65
+
66
+ function _parseFormattedBody ( formattedBody ) {
67
+ // Strip any existing reply fallback and return a HTML string again.
68
+
69
+ // This is greedy and definitely not the most efficient way to do it.
70
+ // However, this function is only called when sending a reply (so: not too
71
+ // often) and it should make sure that all instances of <mx-reply> are gone.
72
+ return formattedBody . replace ( / < m x - r e p l y > [ \s \S ] * < \/ m x - r e p l y > / gi, '' ) ;
73
+ }
74
+
40
75
function _createReplyContent ( targetId , msgtype , body , formattedBody ) {
41
76
return {
42
77
msgtype,
@@ -48,28 +83,40 @@ function _createReplyContent(targetId, msgtype, body, formattedBody) {
48
83
"event_id" : targetId
49
84
}
50
85
}
86
+ // TODO include user mentions
51
87
} ;
52
88
}
53
89
54
90
export function createReplyContent ( entry , msgtype , body , permaLink ) {
55
- // TODO check for absense of sender / body / msgtype / etc?
91
+ // NOTE We assume sender, body, and msgtype are never invalid because they
92
+ // are required fields.
56
93
const nonTextual = fallbackForNonTextualMessage ( entry . content . msgtype ) ;
57
94
const prefix = fallbackPrefix ( entry . content . msgtype ) ;
58
95
const sender = entry . sender ;
59
- const name = entry . displayName || sender ;
60
-
61
- const formattedBody = nonTextual || entry . content . formatted_body ||
62
- ( entry . content . body && htmlEscape ( entry . content . body ) ) || "" ;
63
- const formattedFallback = `<mx-reply><blockquote>In reply to ${ prefix } ` +
64
- `<a href="https://matrix.to/#/${ sender } ">${ name } </a><br />` +
65
- `${ formattedBody } </blockquote></mx-reply>` ;
96
+ const repliedToId = entry . id ;
97
+ // TODO collect user mentions (sender and any previous mentions)
66
98
99
+ // Generate new plain body with plain reply fallback
67
100
const plainBody = nonTextual || entry . content . body || "" ;
68
- const bodyLines = plainBody . split ( "\n" ) ;
101
+ const bodyLines = _parsePlainBody ( plainBody ) ;
69
102
bodyLines [ 0 ] = `> ${ prefix } <${ sender } > ${ bodyLines [ 0 ] } `
70
103
const plainFallback = bodyLines . join ( "\n> " ) ;
71
-
72
104
const newBody = plainFallback + '\n\n' + body ;
73
- const newFormattedBody = formattedFallback + htmlEscape ( body ) ;
105
+
106
+ // Generate new formatted body with formatted reply fallback
107
+ const formattedBody = nonTextual || entry . content . formatted_body ||
108
+ ( entry . content . body && htmlEscape ( entry . content . body ) ) || "" ;
109
+ const cleanedFormattedBody = _parseFormattedBody ( formattedBody ) ;
110
+ const formattedFallback =
111
+ `<mx-reply>` +
112
+ `<blockquote>` +
113
+ `<a href="${ permaLink } ">In reply to</a>` +
114
+ `${ prefix } <a href="https://matrix.to/#/${ sender } ">${ sender } </a>` +
115
+ `<br />` +
116
+ `${ cleanedFormattedBody } ` +
117
+ `</blockquote>` +
118
+ `</mx-reply>` ;
119
+ const newFormattedBody = formattedFallback + htmlEscape ( body ) . replaceAll ( '\n' , '<br/>' ) ;
120
+
74
121
return _createReplyContent ( entry . id , msgtype , newBody , newFormattedBody ) ;
75
122
}
0 commit comments